I finally get late static binding in PHP

Static inheritance in PHP (and really any language) can get tricky sometimes, especially when you’re trying to figure out what self is currently referring to. In PHP, self is always applied to the class that has that declaration, not necessarily the child class. Hmm… that reads weird, let’s make an example.

abstract class a
{
    public static function who()
    {
        return 'a';
    }

    public function info_self()
    {
        return self::who();
    }
}

class b extends a
{
    public static function who()
    {
        return 'b';
    }
}

In this example your brain might be saying that b overrode the who method so calling b->info_self() should use the override. You’d be wrong.

If you create an instance of b and call the info_self() method you will get a instead of b because the info_self method invokes its own self::who() and does not come back up (or down) the inheritance chain to b.

The good news is that they helped us in PHP 5.3 by adding the static:: keyword (variable introduction?) and a feature called Late Static Binding. The basic idea is that PHP will hold on to the child class as it walks up (or down) the inheritance chain and will then invoke the method on the nearest child caller instead.

You can add another method to the base class above to see this in action:

abstract class a
{
    public static function who()
    {
        return 'a';
    }

    public function info_self()
    {
        return self::who();
    }

    public function info_static()
    {
        return static::who();
    }
}

Then run:

$b = new \b();
dump( $b->info_self() );
dump( $b->info_static() );

The info_self method is the old one and will return a and the info_static is the new one that knows the context (or specific subclass) of where that method was actually called.

Sweet.