Chris Camaratta
Chris Camaratta

Reputation: 2769

What does `$this` mean when used outside class in PHP 5?

I'm migrating an application from a PHP 5 server to a PHP 7 server for a client. I've come across some nonsensical code that works (in the sense that it does not throw errors or warnings) on the PHP 5 server but crashes on the PHP 7 server. I'm trying to understand the semantics of $this in PHP 5 that would help me decipher what the code is doing:

if ( !is_object( $this ) )
{
    require_once '' . '/model/Model.php';

    $me = new Controller( false );
    $me->invoke();
}
else
{
    require_once 'model/Model.php';
}

The offending statement is of course if ( !is_object( $this ) ); $this is illegal outside of a class. My guess is the code is attempting to instantiate some kind of singleton and can only assume the semantics of $this in PHP5 resolved $this as nullish when used outside of a class. I am having trouble confirming this.

Did PHP ever allow this kind of usage? Or was there some configuration option that enabled it to be used this way? What did $this mean when used this way?

Upvotes: 2

Views: 77

Answers (1)

iainn
iainn

Reputation: 17417

No, using $this in global scope won't have ever done anything useful*

It was actually PHP 7.1 that made the change - specifically the Fix inconsistent behavior of $this variable RFC. Before that, PHP just treated it the same as any other undefined variable. Now you'll see a fatal error instead, see https://3v4l.org/b4Wte

I'd assume that this code was copied from a class method, where it looks like it was trying to run from both a static and object context.

The really quick change would be to swap out the is_object check for isset, which can still run safely with $this. But since the line will always be true, you might as well just replace the whole thing with

require_once '' . '/model/Model.php';

$me = new Controller( false );
$me->invoke();

* Strictly speaking, all the way back in PHP 4 you could have redefined $this to point to whatever you want, but I'm guessing that probably doesn't apply here.

Upvotes: 6

Related Questions