考虑这个课程:
class test
{
public function __set($n, $v)
{
echo "__set() called\n";
$this->other_set($n, $v, true);
}
public function other_set($name, $value)
{
echo "other_set() called\n";
$this->$name = $value;
}
public function t()
{
$this->t = true;
}
}
我正在重载PHP的魔术__set()
方法。每当我在test
类的对象中设置属性时,它都会调用__set()
,然后调用other_set()
。
$obj = new test;
$test->prop = 10;
/* prints the following */
__set() called
other_set() called
但是other_set()
有以下行$this->$name = $value
。这不应该导致调用__set()
,导致无限递归吗?
我认为只有在课外设置时才会调用__set()
。但是,如果您调用方法t()
,您可以清楚地看到它__set()
。
答案 0 :(得分:12)
__set
is only called once per attempt for a given property name.如果它(或它调用的任何东西)试图设置相同的属性,PHP将不会再次调用__set
- 它只会在对象上设置属性。
答案 1 :(得分:2)
将数据写入无法访问的属性时,会运行__ set()
例如:
class foo {
private $attributes;
public $bar;
public function __construct() {
$this->attributes = array();
}
public function __set($n, $v) {
echo "__set() called\n";
$this->attributes[$n] = $v;
}
}
$x = new foo;
$x->prop = "value";
$x->attributes = "value";
$x->bar = "hello world";
在这种情况下,$x->prop
无法访问,系统会调用__set
。 $x->attributes
也无法访问,因此将调用__set
。但是,$x->bar
可公开访问,因此__set
将不被调用。
同样,在__set
方法中,$this->attribtues
是可访问的,因此没有递归。
在上面的示例代码中,$this->$name
可在其调用的范围内访问,因此不会调用__set
。