【问题标题】:Strange behavior adding this object to this static array将此对象添加到此静态数组的奇怪行为
【发布时间】:2014-03-07 14:57:10
【问题描述】:

目前我用这段代码进行测试:

<?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

【问题讨论】:

    标签: php oop static-array


    【解决方案1】:

    那是因为您的对象(即内部上下文中的 $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() - 然后你会看到对象实际上是相同的。您的代码示例(即复制尚未修复):

    数组(2){ [0]=> 对象(警报)#1 (2) { [“类型”:“警报”:私人]=> 字符串(5)“错误” [“消息”:“警报”:私人]=> 字符串(6)“测试 2” } [1]=> 对象(警报)#1 (2) { [“类型”:“警报”:私人]=> 字符串(5)“错误” [“消息”:“警报”:私人]=> 字符串(6)“测试 2” } }

    -如您所见,那里的对象是相同的。

    【讨论】:

      【解决方案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>";
      

      【讨论】:

        【解决方案3】:

        您看到的问题是因为您的代码两次更改了同一个对象。 第一次调用会设置数据“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
            )
        
        )
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-08-11
          • 2021-09-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-20
          • 2012-01-17
          相关资源
          最近更新 更多