通过魔术方法修改PHP数组元素(__get和__set)

时间:2015-08-11 15:15:45

标签: php overloading magic-methods

我有以下课程:

/**
 * @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公共属性未明确定义,可通过魔术方法访问。

在普通属性中设置然后修改数组元素时,它可以正常工作:

$foo = new Foo();
$foo->barNormal = ['baz' => 1];
echo $foo->barNormal['baz'];
$foo->barNormal['baz'] = 2;
echo ',' . $foo->barNormal['baz'];

输出“1,2”,正如预期的那样。

但是当使用魔法属性时,它不会:

$foo = new Foo();
$foo->barMagic = ['baz' => 1];
echo $foo->barMagic['baz'];
$foo->barMagic['baz'] = 2;
echo ',' . $foo->barMagic['baz'];

输出“1,1”!

在PHP中是否有办法以与普通方式相同的方式访问魔术属性中的数组元素?

ArrayAccess接口似乎处理比我需要的级别高一级的数组访问。

1 个答案:

答案 0 :(得分:0)

真正的答案很棘手,并且涉及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;
    }
}

现在它有效。请注意,这两个片段应该完全等效,但它们不是。谢谢大家的贡献,你把我带到了那里。