为什么魔术方法'__get'被调用了两次?

时间:2011-09-27 10:23:27

标签: php

我见过如下的代码,奇怪的是,__get方法被调用了两次,为什么?

class Foo {
    private $bar;

    function __get($name){
        echo "__get is called!";
        return $this->$name;
    }

    function __unset($name){
        unset($this->$name);
    }
}
$foo = new Foo;
unset($foo->bar);
echo $foo->bar;

注意unset($foo->bar)不会致电__get

3 个答案:

答案 0 :(得分:2)

对我来说,它看起来像一个bug。放一些调试代码(如下)并查看结果:

<?php

class Foo {
    private $bar;

    function __get($name){
        echo "__get(".$name.") is called!\n";
        debug_print_backtrace();
        $x = $this->$name;
        return $x;
    }

    function __unset($name){
        unset($this->$name);

        echo "Value of ". $name ." After unsetting is \n";
        echo $this->$name;
        echo  "\n";
    }
}
echo "Before\n";
$foo = new Foo;
echo "After1\n";
unset($foo->bar);
echo "After2\n";
echo $foo->bar;
echo "After3\n";
echo $foo->not_found;
?>

结果是:

Before
After1
Value of bar After unsetting is
__get(bar) is called!
#0  Foo->__get(bar) called at [E:\temp\t1.php:17]
#1  Foo->__unset(bar) called at [E:\temp\t1.php:24]
PHP Notice:  Undefined property: Foo::$bar in E:\temp\t1.php on line 9

After2
__get(bar) is called!
#0  Foo->__get(bar) called at [E:\temp\t1.php:26]
__get(bar) is called!
#0  Foo->__get(bar) called at [E:\temp\t1.php:9]
#1  Foo->__get(bar) called at [E:\temp\t1.php:26]
PHP Notice:  Undefined property: Foo::$bar in E:\temp\t1.php on line 9
After3
__get(not_found) is called!
#0  Foo->__get(not_found) called at [E:\temp\t1.php:28]
PHP Notice:  Undefined property: Foo::$not_found in E:\temp\t1.php on line 9

答案 1 :(得分:1)

中调用

1)

 return $this->$name;

2)

 echo $foo->bar;
代码中的

    class Foo {
        private $bar;

        function __get($name){
            echo "__get is called!";
            return $this->$name;  *** here ***
        }

        function __unset($name){
            unset($this->$name);
        }
    }
    $foo = new Foo;
    unset($foo->bar);
    echo $foo->bar;   *** and here ***

__ get()用于从无法访问的属性中读取数据。

所以,取消设置变量,转$ foo-&gt; bar和$ this-&gt; bar无法访问。但是,如果取消设置,则无法访问$ foo-&gt;栏,但可以访问$ this-&gt;栏。

但是,我不知道PHP如何避免递归调用该函数。可能是PHP很聪明,或者变量在某些时候是自我设置的。

答案 2 :(得分:0)

每次尝试访问变量时都会调用magic __get函数。如果你看一下你的代码,你就会这样做两次。一旦进入unset函数,一次进入echo函数。

未设置(的 $ foo-&GT;栏 );
echo $ foo-&gt; bar ;