开发者

Why the magic method '__get' has been called twice?

I have seen some code like below, and it is strange that the __get method has been called twice, why?

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;

Attention: unset($foo->bar) will not call the __get开发者_如何转开发.


For me, it looks like a bug. Put some debugging code (the following) and see the result:

<?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;
?>

The result is:

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


invoked in

1)

 return $this->$name;

2)

 echo $foo->bar;

in the code:

    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() is utilized for reading data from inaccessible properties.

so, un-setting the variable, turn $foo->bar and $this->bar inaccessible. However, if unset is removed then $foo->bar is inaccessible but $this->bar is accessible.

However, i don't know how PHP avoid to call the function recursively. May be PHP is smart or the variable is self-setting at some point.


The magic __get function is called everytime you try to access a variable. If you look at your code, you do this exactly 2 times. Once in the unset function and once in the echo function.

unset($foo->bar);
echo $foo->bar;

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜