Endless recursion in PHP echo expression

Why is this code calling infinite recursion?

class Foo {
    public static function newFoo() { return new Foo(); }
    public function __toString() {
        return "{${Foo::newFoo()}}";
    }
}

echo new Foo(); // Infinite recursion
new Foo();      // Finishes normally

      

Is it because it __toString()

returns an object? But this is not possible, because according to the docs

This method must return a string, otherwise an E_RECOVERABLE_ERROR level error is emitted. ( ref )

Or is it just infinitely recursive within the method __toString()

?

+3


source to share


2 answers


echo new Foo();

      

creates Foo

and tries to execute echo

it in order to do so by casting the object into a string that calls the magic method __toString

.

In this method, however, you call a static method Foo::newFoo

that returns a new object, which is outputted again to the string in __toString

, which is called this way again.

So yes, here's an infinite recursion.



To clarify:

public function __toString() {
    return "{${Foo::newFoo()}}";
}

      

equivalent to

public function __toString() {
    $foo = Foo::newFoo();
    return "$foo"; // this is a cast as string, which invokes __toString() again.
}

      

+7


source


Because you call it endlessly.

you echoed echo new Foo();

and you call it again:

'return "{${Foo::newFoo()}}";'

public static function newFoo() { return new Foo(); }

      

here's a sample simulation:

echo new Foo();

      

will call this:

public function __toString() {
   return "{${Foo::newFoo()}}"; 
}

      

// and you called

public static function newFoo() { return new Foo(); }

      



// and will execute again

public function __toString() {
   return "{${Foo::newFoo()}}"; 
}

      

// and will call again

public static function newFoo() { return new Foo(); }

      



// and do it again and again

public function __toString() {
   return "{${Foo::newFoo()}}"; 
}

      

// and call again and again

public static function newFoo() { return new Foo(); }

      



Ooooohhh I'm already in an endless loop, I'm just kidding.

But yes, it's an endless loop.

+1


source







All Articles