This manages to create a new property on the object. But, can someone explain, with supporting links, why setAttrib behaves in two different ways? Why doesn’t it cause a… wait for it… stack overflow!!??
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);
produces…
setAttrib
__set
setAttrib
object(Test)#1 (1) {
["hey"]=>
string(8) "It works"
}
Edit: I’m not looking for an alternative. I’m looking for the reason why this works.
You are not the only one who seems to have notice that non-recursive behaviour : this comment on the manual’s page states :
And, a bit later on the same page, there is this one, which states :
And, on PHP’s bugtracker, there is #47215 : magic method __set() is bypassed on recursive call, which says :
And it has been closed as :
That bug-report, itself, points to this blog-post, which ends by this sentence (quoting, emphasis mine) :