6

经过一番研究,我最终找到了一个我很快要在这里问的问题的答案;你如何通过 PHP 中的__get__set魔法方法处理数组?每当我尝试使用类似的东西设置一个值$object->foo['bar'] = 42;时,它似乎都会默默地丢弃它。

无论如何,答案很简单;该__get方法只需要通过引用返回。在它前面扔了一个&符号之后,果然它起作用了。

我的问题实际上是为什么?我似乎无法理解为什么这是有效的。__get按引用返回如何影响__set使用多维数组?

编辑:顺便说一下,运行 PHP 5.3.1

4

3 回答 3

4

在 PHP 中,当您从函数返回值时,您可以考虑复制该值(除非它是一个类)。在这种情况下,__get除非您返回要编辑的实际内容,否则所有更改都会对副本进行,然后将其丢弃。

于 2010-11-30T04:22:34.007 回答
3

在这种特殊情况下,__set实际上并没有被调用。如果你分解它发生的事情,它应该更有意义:

$tmp = $object->__get('foo');
$tmp['bar'] = 42

如果__get没有返回引用,则不是将 42 分配给原始对象的“条形”索引,而是分配给原始对象副本的“条形”索引。

于 2010-11-30T04:30:00.953 回答
2

也许更清楚:

//PHP will try to interpret this:
$object->foo['bar'] = 42

//The PHP interpreter will try to evaluate first 
$object->foo

//To do this, it will call 
$object->__get('foo')
// and not __get("foo['bar']"). __get() has no idea about ['bar']

//If we have get defined as &__get(), this will return $_data['foo'] element 
//by reference.
//This array element has some value, like a string: 
$_data['foo'] = 'value';

//Then, after __get returns, the PHP interpreter will add ['bar'] to that
//reference.
$_data['foo']['bar']

//Array element $_data['foo'] becomes an array with one key, 'bar'. 
$_data['foo'] = array('bar' => null)

//That key will be assigned the value 42
$_data['foo']['bar'] = 42

//42 will be stored in $_data array because __get() returned a reference in that
//array. If __get() would return the array element by value, PHP would have to 
//create a temporary variable for that element (like $tmp). Then we would make 
//that variable an array with $tmp['bar'] and assign 42 to that key. As soon 
//as php would continue to the next line of code, that $tmp variable would 
//not be used any more and it will be garbage collected.
于 2012-07-02T06:50:44.060 回答