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;
精彩评论