简体   繁体   English

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

[英]Modifying a PHP array element via magic methods (__get and __set)

I have the following class: 我有以下课程:

/**
 * @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;
    }
}

As you can see, the $barMagic public property is not defined explicitly, it's accessed via the magic methods. 如您所见,没有明确定义$ barMagic公共属性,而是通过magic方法访问它。

When setting and then modifying an array element in the normal attribute, it works fine: 当设置然后修改normal属性中的数组元素时,它可以正常工作:

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

It outputs "1,2", just as intended. 它按预期输出“ 1,2”。

But when using the magic property, it does not: 但是,在使用magic属性时,它不会:

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

It outputs "1,1"! 输出“ 1,1”!

Is there a way in PHP to access array elements in magic properties the same way as normal ones? PHP中是否有一种方法可以像普通属性一样访问魔术属性中的数组元素?

The ArrayAccess interface seems to deal with array access one level higher than I need it. ArrayAccess接口似乎处理的数组访问权限比我需要的高一级。

The real answer is tricky and involves some bug/inconsistency in the PHP engine. 真正的答案很棘手,并且在PHP引擎中涉及一些错误/不一致。 As commentors suggested, I added the "&" (return by reference) character before __get(). 如评论员所建议,我在__get()之前添加了“&”(按引用返回)字符。 So new code: 所以新的代码:

public function &__get($name) {
    return isset($this->attributes[$name]) ? $this->attributes[$name] : null;
}

but this gives 但这给

Notice: Only variable references should be returned by reference in ....

I had to change it to 我不得不将其更改为

public function &__get($name) {
    if (isset($this->attributes[$name])) {
        return $this->attributes[$name];
    } else {
        return null;
    }
}

and now it works. 现在可以了。 Note that the two snippets should be completely equivalent, but they are not. 请注意,这两个代码段应该完全等效,但事实并非完全相同。 Thank you all for the contribution, you took me halfway there. 谢谢大家的贡献,您把我带到了一半。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM