Почему этот код вызывает бесконечную рекурсию?
class Foo {
public static function newFoo() { return new Foo(); }
public function __toString() {
return "{${Foo::newFoo()}}";
}
}
echo new Foo(); // Infinite recursion
new Foo(); // Finishes normally
Это потому что __toString()
возвращает объект? Но это не может быть возможно, потому что в соответствии с документами
Этот метод должен возвращать строку, так как в противном случае выдается фатальная ошибка уровня E_RECOVERABLE_ERROR. (ссылка)
Или это просто бесконечно повторяется в пределах __toString()
метод?
echo new Foo();
создает Foo
и пытается echo
это, чтобы сделать это, он бросает объект в строку, вызывая магический метод __toString
,
В этом методе, однако, вы вызываете статический метод Foo::newFoo
, который возвращает новый объект, который снова приводится к строке в __toString
сам, который так снова вызывается.
Так что да, здесь бесконечная рекурсия.
Чтобы уточнить:
public function __toString() {
return "{${Foo::newFoo()}}";
}
эквивалентно
public function __toString() {
$foo = Foo::newFoo();
return "$foo"; // this is a cast as string, which invokes __toString() again.
}
Потому что вы называете это бесконечно ..
ты повторил echo new Foo();
и вы звоните снова с:
'return "{${Foo::newFoo()}}";'
public static function newFoo() { return new Foo(); }
вот пример симуляции:
echo new Foo();
назову это:
public function __toString() {
return "{${Foo::newFoo()}}";
}
// и ты позвонил
public static function newFoo() { return new Foo(); }
// и снова выполним
public function __toString() {
return "{${Foo::newFoo()}}";
}
// и снова позвоним
public static function newFoo() { return new Foo(); }
// и будет снова и снова выполнять
public function __toString() {
return "{${Foo::newFoo()}}";
}
// и будем снова и снова звонить
public static function newFoo() { return new Foo(); }
Ooooohhh Я уже в бесконечной петле, я просто шучу ..
Но да, это бесконечный цикл ..