【问题标题】:Reference problem when returning an object from array in PHP从 PHP 中的数组返回对象时的引用问题
【发布时间】:2010-05-12 13:00:25
【问题描述】:

我有一个参考问题;这个例子应该比我更具描述性: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"));

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

$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

如果它丢失了参考。

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

有什么想法吗?

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

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

【问题讨论】:

  • 为什么要访问空引用?你会期待什么样的结果?

标签: php arrays object reference


【解决方案1】:

您更改了指向 null 的元素上的 another_var 变量。 这意味着您根本不会更改集合元素。这就是为什么你得到值“默认”......

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

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

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

编辑:

如果您想更改该位置的对象,您必须访问您的集合(可能是关联数组)并更改该位置的对象。您可以通过提供 set_element($key, $value) 来做到这一点。

<? 

class Collection
{
  private $elements;

  public set_element($key, $value)
  {
     $elements[$key] = $value;
  }

  public get_element($key)
  {
     return $elements[$key];
  }
}

?>

【讨论】:

    【解决方案2】:

    $element 有对对象的引用,没错,但如果你这样做了

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

    您为 $element 分配了一个新值,并且您失去了对前一个对象的引用。

    如果我这样做:

    $element = new A();
    

    然后

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

    我访问B 类对象的方法foo 而不是A,因为新值已分配给$element

    【讨论】:

      【解决方案3】:

      您检索了一个引用并将其分配给变量$element。然后你切换变量来引用一个新对象而不是操作旧对象。

      【讨论】:

        【解决方案4】:

        当你这样做时:

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

        您将 another_var 的值设置为空对象,因为 $element 现在为空。 如果你试试这个

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

        那么它应该可以工作

        【讨论】:

          猜你喜欢
          • 2019-09-03
          • 1970-01-01
          • 1970-01-01
          • 2015-07-26
          • 1970-01-01
          • 1970-01-01
          • 2014-07-14
          • 1970-01-01
          • 2014-05-23
          相关资源
          最近更新 更多