我有参考问题;这个例子应该比我更具描述性: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
就好像失去了参考。
那么,怎么了?我有元素变量的引用而不是元素本身?
有什么想法吗?
编辑:为了澄清,我想用另一个“更改”对象元素,但保持数组中的位置。
现在我明白以这种方式是不可能的:(
答案 0 :(得分:1)
$element
有对象的引用,这是正确的,但如果你这样做
$element = null; //or $element = new GenericObject();
您为$element
分配了一个新值,并且您放弃了对前一个对象的引用。
如果我这样做:
$element = new A();
然后
$element = new B();
$element->foo();
我访问了foo
类对象的方法B
,而不是A
,因为新值已分配给$element
。
答案 1 :(得分:1)
您已检索参考并将其分配给变量$element
。然后,您切换变量以引用新对象,而不是操纵旧对象。
答案 2 :(得分:1)
您在指向null的元素上更改another_var变量。 这意味着您根本不需要更改集合元素。这就是为什么你得到“默认”值的原因......
即使您正在使用引用,引用本身也会按值传递。这应该更清楚:
$a = new Object();
$b = $a;
$a = null;
$b
在这种情况下仍为new Object()
。
编辑:
如果要更改该位置的对象,则必须访问Collection(可能是关联数组)并更改该位置的对象。您可以通过提供set_element($ key,$ value)来完成此操作。
<?
class Collection
{
private $elements;
public set_element($key, $value)
{
$elements[$key] = $value;
}
public get_element($key)
{
return $elements[$key];
}
}
?>
答案 3 :(得分:0)
执行此操作时:
$element = null;
$element->another_var = "bla";
您将another_var的值设置为null对象,因为$ element现在为null。 如果你试试这个
$element->another_var = "bla";
$element = null;
然后它应该工作