PHP魔术方法__get和[]使值消失

时间:2015-05-12 15:59:49

标签: php arrays properties get

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

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); - 它工作得很好。但我想了解这种情况并拥有一个通用的解决方案,而无需首先启动数组。有办法解决这个问题吗?

2 个答案:

答案 0 :(得分:3)

$testObj->testArr[] = 1;

给你一个通知:

  

注意:间接修改重载属性T :: $ testArr对第24行的test.php没有影响

确保您的错误报告turned on

答案 1 :(得分:0)

如果从__get(或任何函数/方法)返回一个数组,则返回空数组的副本,而不是对该数组的引用。这意味着您正在尝试将一个元素添加到一个没有名称的变量中,一旦修改它就无法访问它,因此通知:

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

但是在接下来的两次调用中,键所表示的属性是类实例的真实部分,因此不再调用__get。该变量实际存在,并且您将其作为类实例的任何其他变量附加到它。

通过向名为$ vals的类添加本地数组变量并更改所有这些代码,您可以看到这是真的

$this->{$property}

$this->vals[$property]

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