代码之家  ›  专栏  ›  技术社区  ›  apelliciari

在PHP中从数组返回对象时出现引用问题

  •  0
  • apelliciari  · 技术社区  · 16 年前

    我有一个参考问题;这个例子应该比我更具描述性:p

    我有一个类,它有一个对象数组,并通过键(字符串)检索它们,就像关联数组:

    class Collection {
    
        public $elements;
    
        function  __construct() {
            $this->elements = array();
        }
    
        public function get_element($key) {
    
            foreach($this->elements as $element) {
                if ($element->key == $key) {
    
                    return $element;
                    break;
                }
            }
            return null;
    
        }
    
        public function add_element ($element) {
            $this->elements[] = $element;
        }
    
    }
    

    然后我有一个对象(通用),有一个键和一些变量:

    class Element {
    
        public $key;
        public $another_var;
    
        public function __construct($key) {
            $this->key = $key;
            $this->another_var = "default";
        }
    }
    

    现在,我创建了我的收藏:

    $collection = new Collection();
    
    $collection->add_element(new Element("test1"));
    $collection->add_element(new Element("test2"));
    

    然后我尝试更改“array”中包含的元素的变量:

    $element = $collection->get_element("test1");
    $element->another_var = "random_string";
    echo $collection->get_element("test1")->another_var;
    

    好的,输出是

    random_string
    

    所以我知道我的对象在引用模式下被传递给$element。

    但是如果我这样做了,那么:

    $element = $collection->get_element("test1");
    $element = null; //or $element = new GenericObject();
    $element->another_var = "bla";
    echo $collection->get_element("test1")->another_var;
    

    输出是

    default
    

    就像它失去了参考。

    那么,怎么了?我得到了元素变量的引用,而不是元素本身的引用?

    有什么想法吗?

    编辑:为了澄清,我想用另一个“更改”对象元素,但要保留数组中的位置。

    现在我明白这是不可能的:(

    4 回复  |  直到 16 年前
        1
  •  1
  •   Simon    16 年前

    更改指向空的元素上的另一个变量。 这意味着您根本不更改集合元素。这就是为什么你得到值“默认”…

    即使使用的是引用,引用本身也是按值传递的。这应该更清楚:

    $a = new Object();
    $b = $a;
    $a = null;
    

    $b 仍然是 new Object() 在这种情况下。

    编辑:

    如果要更改该位置的对象,则必须访问集合(可能是关联数组)并更改该位置的对象。您可以通过提供一个集合元素($key$value)来实现这一点。

    <? 
    
    class Collection
    {
      private $elements;
    
      public set_element($key, $value)
      {
         $elements[$key] = $value;
      }
    
      public get_element($key)
      {
         return $elements[$key];
      }
    }
    
    ?>
    
        2
  •  1
  •   Felix Kling    16 年前

    $element 有对象的引用,没错,但是如果你有

    $element = null; //or $element = new GenericObject();
    

    将新值赋给 元元 然后你松开了对前一个对象的引用。

    如果我这样做:

    $element = new A();
    

    然后

    $element = new B();
    $element->foo();
    

    我使用这个方法 foo 类对象的 B 而不是 A 作为新值分配给 元元 .

        3
  •  1
  •   Fletcher Moore    16 年前

    检索引用并将其分配给变量 $element . 然后,您切换变量以引用新对象,而不是操作旧对象。

        4
  •  0
  •   Pierre    16 年前

    当你这样做的时候:

    $element = null;
    $element->another_var = "bla";
    

    您正在将另一个变量的值设置为空对象,因为$element现在为空。 如果你尝试这个

    $element->another_var = "bla";    
    $element = null;
    

    那么它就可以工作了