将此对象添加到此静态数组的奇怪行为

时间:2014-02-10 10:22:35

标签: php oop static-array

目前我用这段代码测试:

<?php
    class Alert {
        private $type;
        private $message;
        public static $_alerts = array();

        public function add($type, $message) {
            $this->type = $type;
            $this->message = $message;
            self::$_alerts[] = $this;
        }
    }

    $alert = new Alert();

    $alert->add("warning", "test 1");
    $alert->add("error", "test 2");

    echo "<pre>";
    print_r(Alert::$_alerts);
    echo "</pre>";

但我的结果并不像预期的那样:

Array
(
    [0] => Alert Object
        (
            [type:Alert:private] => error
            [message:Alert:private] => test 2
        )

    [1] => Alert Object
        (
            [type:Alert:private] => error
            [message:Alert:private] => test 2
        )

)

为什么我添加的对象发生了变化?

测试区域:http://codepad.viper-7.com/6q2H2A

3 个答案:

答案 0 :(得分:2)

这是因为您的对象(即内部上下文中的$this)将be copied by reference,而不是值。要按值复制,您需要执行以下操作:

    public function add($type, $message) 
    {
        $this->type = $type;
        $this->message = $message;
        self::$_alerts[] = clone $this;
    }

作为替代方案,你需要实例化(例如,像new self这样的结构 - 但clone似乎在这里更灵活)你的对象和你一样多次希望复制。

顺便说一句,有很简单的方法来实现正在发生的事情。使用var_dump()代替print_r() - 然后您会看到对象实际上是相同的。代码示例(即复制 尚未修复的地方):

array(2) {
  [0]=>
  object(Alert)#1 (2) {
    ["type":"Alert":private]=>
    string(5) "error"
    ["message":"Alert":private]=>
    string(6) "test 2"
  }
  [1]=>
  object(Alert)#1 (2) {
    ["type":"Alert":private]=>
    string(5) "error"
    ["message":"Alert":private]=>
    string(6) "test 2"
  }
}

- 你可以看到,对象在那里是相同的。

答案 1 :(得分:2)

您可以在$ alerts数组中保存2个对同一对象的引用。您需要为每个警报创建一个新对象,或者执行以下操作:

<?php
    class Alert {
        private $type;
        private $message;
        public static $_alerts = array();

        private function __construct($type,$message){
                $this->type=$type;
                $this->message = $message;
        }

        public function getMessage(){
                return $this->message;
        }

        public function getType(){
                return $this->type;
        }

        public static function add($type, $message) {
            self::$_alerts[] = new self($type,$message);
        }
    }


    Alert::add("warning", "test 1");
    Alert::add("error", "test 2");

    echo "<pre>";
    print_r(Alert::$_alerts);
    echo "</pre>";

答案 2 :(得分:1)

您遇到的问题是因为您的代码正在两次更改同一个对象。 第一次调用时,它会设置数据“warning”和“test 1”,第二次会覆盖这些值。

您可以通过创建对象的新实例并添加数据来解决此问题:

$alert = new Alert();

$alert->add("warning", "test 1");

$alert2 = new Alert();
$alert2->add("error", "test 2");

这应该给出以下结果:

Array
(
    [0] => Alert Object
    (
        [type:Alert:private] => warning
        [message:Alert:private] => test 1
    )

    [1] => Alert Object
    (
        [type:Alert:private] => error
        [message:Alert:private] => test 2
    )

)