PHP魔术__get和[]让价值消失

PHP magic method __get and [] make value disappear

我遇到了一个有趣的问题。在同一操作中使用 [] 创建数组 属性 并为其赋值似乎出错了。

class T
{
    public function __get($property)
    {
        if (!isset($this->{$property}))
        {
            $this->{$property} = array();
        }           

        return $this->{$property};
    }

    public function __set($key, $val)
    {       
        $this->{$key} = $val;
    }

}

$testObj = new T();

$testObj->testArr[] = 1;
$testObj->testArr[] = 2;    
$testObj->testArr[] = 3;

var_dump($testObj->testArr);

输出如下:

array(2) { [0]=> int(2) [1]=> int(3) }

所以1真的像戴帽子的兔子一样神奇地消失在了数组初始化中。如果我在分配之前尝试所有 $testObj->testArr 或者甚至将 1 分配为 $testObj->testArr = array(1); - 它工作得很好。但我想了解情况并有一个通用的解决方案,而不需要先初始化数组。有办法解决这个问题吗?

$testObj->testArr[] = 1;

给你一个通知:

Notice: Indirect modification of overloaded property T::$testArr has no effect in test.php on line 24

确保您收到错误报告 turned on

如果您 return 来自 __get(或任何 function/method)的数组,您是 return 空数组的副本,而不是对该数组的引用.这意味着你试图将一个元素添加到一个没有名称的变量中,一旦你修改它就无法访问它,因此注意:

PHP Notice:  Indirect modification of overloaded property T::$testArr has no effect

但是在接下来的两次调用中,由键表示的 属性 是 class 实例的真实部分,因此不再调用 __get。该变量实际存在,您可以像添加属于 class 实例的任何其他变量一样附加到它。

您可以通过将局部数组变量添加到名为 $vals 的 class 并更改所有这些代码来证明这是真的

$this->{$property}

$this->vals[$property]

现在您收到通知 3 次,每次调用 __get。