我有以下类:
/**
* @property int $barMagic
*/
class Foo
{
public $barNormal;
private $attributes = [];
public function __get($name) {
return isset($this->attributes[$name]) ? $this->attributes[$name] : null;
}
public function __set($name, $value)
{
$this->attributes[$name] = $value;
}
}
可以看到,$barMagic公共属性没有显式定义,它是通过magic方法访问的。
当在normal属性中设置和修改数组元素时,它工作得很好:
$foo = new Foo();
$foo->barNormal = ['baz' => 1];
echo $foo->barNormal['baz'];
$foo->barNormal['baz'] = 2;
echo ',' . $foo->barNormal['baz'];
输出"1,2",和预期的一样。
但是当使用magic属性时,它不会:
$foo = new Foo();
$foo->barMagic = ['baz' => 1];
echo $foo->barMagic['baz'];
$foo->barMagic['baz'] = 2;
echo ',' . $foo->barMagic['baz'];
输出"1,1"!
是否有一种方法在PHP访问数组元素在魔术属性的相同方式作为正常的?
ArrayAccess接口处理数组访问的级别似乎比我需要的要高一级。
真正的答案是棘手的,涉及PHP引擎中的一些错误/不一致。正如评论者建议的那样,我加上了"&"(返回引用)字符在__get()之前。新代码:
public function &__get($name) {
return isset($this->attributes[$name]) ? $this->attributes[$name] : null;
}
但是这里给出
Notice: Only variable references should be returned by reference in ....
我必须把它改成
public function &__get($name) {
if (isset($this->attributes[$name])) {
return $this->attributes[$name];
} else {
return null;
}
}
,现在它工作了。请注意,这两个代码片段应该是完全相等的,但事实并非如此。谢谢大家的帮助,你们让我成功了一半。