这设法在对象上创建一个新属性。但是,有人可以通过支持链接解释为什么 setAttrib
有两种不同的行为方式吗?为什么它不会导致……等等……堆栈溢出!!??
class Test
{
public function setAttrib( $key, $value ) {
echo "setAttrib\n";
// first time: calls $this->__set($key, $value)
// second time: just sets a public property (but, when exactly was it created?)
$this->$key = $value;
}
public function __set( $key, $value ) {
echo "__set\n";
$this->setAttrib($key, $value);
}
}
$test = new Test();
$test->setAttrib('hey', 'It works');
var_dump($test);
产生...
setAttrib
__set
setAttrib
object(Test)#1 (1) {
["hey"]=>
string(8) "It works"
}
编辑:我不是在寻找替代方案。 我正在寻找它起作用的原因。
最佳答案
您似乎不是唯一注意到非递归行为的人:this comment on the manual's page状态:
2 - PHP will not recursively call one magic method from within itself (at least for the same
$name
).
稍后在同一页上,有 this one ,其中指出:
The recursion detection feature can prove especially perilous when using
__set
. When PHP comes across a statement that would usually call__set
but would lead to recursion, rather than firing off a warning or simply not executing the statement it will act as though there is no__set
method defined at all.
The default behaviour in this instance is to dynamically add the specified property to the object thus breaking the desired functionality of all further calls to__set
or__get
for that property.
而且,在 PHP 的错误追踪器上,有 #47215 : magic method __set() is bypassed on recursive call ,它说:
Magic method
__set()
is bypassed on recursive call.
PHP automatically creates a property on instance instead of recursively calling__set()
or instead of throwing a recursivity error
它已被关闭为:
Thank you for taking the time to write to us, but this is not a bug.
该错误报告本身指向 this blog-post ,以这句话结束(引用,强调我的):
After all I think it may not be a bug but expected behaviour, otherwise we could not be able to define object properties from within
__set()
method.
关于PHP:__set 函数行为每次都不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1948844/