Бесконечная рекурсия в PHP эхо-оператора

Почему этот код вызывает бесконечную рекурсию?

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() метод?

3

Решение

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.
}
7

Другие решения

Потому что вы называете это бесконечно ..

ты повторил 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 Я уже в бесконечной петле, я просто шучу ..

Но да, это бесконечный цикл ..

1

По вопросам рекламы [email protected]