有人在Twitter上将其发布为php #wtf:
class A
{
private $b;
function __construct()
{
unset($this->b);
}
function __get($n)
{
echo '!broken!';
return $this->$n;
}
}
$a = new A;
$a->b; //EDIT: original question had var_dump($a->b);
//output:
!broken!!broken!
我对此的第一反应是$ a-> b触发第一个回声的__get(),然后返回$ this-> $ n触发__get再次导致$ this-> b仍然不存在,可能是__get()中包含的代码应该处理。 PHP自动检测无限递归并在那里停止。这是有道理的,但另一方面,PHP仅为欠定义属性A :: $ b提供E_NOTICE错误。
所以我的问题是,我是否正确PHP自动检测无限递归?我怎么能说出来?还是有其他理由来解释给出的输出?
答案 0 :(得分:0)
在类中,不隐藏私有变量。因此,在执行下面的代码时,您可以获得变量$ b,而无需调用__get():
class A {
private $b;
function get_b()
{
return $this->b;
}
}
$a = new A;
echo $a->get_b();
但在下面一个,你不能 - 它会调用函数__get():
class A
{
private $b;
function get_b()
{
return $this->b;
}
}
$a = new A; echo $a->b;
所以在你的例子中:
A级{ 私人$ b;
function __construct() { unset($this->b); } function __get($n) { echo '!broken!'; return $this->$n; } }
$a = new A; // Here you called unset, and since it doesn't know the "b", it calls __get().
var_dump($a->b); // Again here $a->b is not "exists" or "hidden", so it calls __get() again.
在__get()中,“return $ this-> $ n”确实知道变量$ n - 也就是说$ b(就像我的第一个代码示例 - 函数get_b())。所以它实际上不是无限递归,它就像任何其他函数调用一样;)