Ответ 1
__set
вызывается только один раз за попытку для данного имени свойства. Если он (или что-то, что он вызывает) пытается установить тот же свойство, PHP не вызовет __set
снова - он просто установит свойство на объект.
Рассмотрим этот класс:
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 magic __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()
.
__set
вызывается только один раз за попытку для данного имени свойства. Если он (или что-то, что он вызывает) пытается установить тот же свойство, PHP не вызовет __set
снова - он просто установит свойство на объект.
Из документации:
__ 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
не вызывается.