WTF is Late Static Binding in PHP?


PHP / Thursday, June 28th, 2018

One of the features in “advanced” PHP you come across is Late Static Binding. There are two things that make this feature very interesting:

  • It is remarkably useful
  • It is extremely poorly explained in the official docs

So if you’ve heard of this term the first-time, or like me, have lost a few hair over what exactly does it mean, you’ve come to the right place.

First, let’s get a few facts in order:

  • Late Static Binding applies only when there is inheritance involved. No inheritance, no Late Static Binding.
  • The “static” in “Late Static Binding” means that this idea crops up only when static class members are involved.

So, only inheritance, and only static members. Some people even call it “static inheritance”, but I think that term gives the concept an unnecessary aura of erudition, and thus, intimidation.

Anyway, generally we don’t work in inheritance hierarchies where a lot of static members are involved in base and derived classes. But if there’s ever a need, a nasty surprise awaits us. Let’s learn this through an example.

Suppose you are designing a game where Minions are an important NPC entity (yes, you can’t exactly do that because of copyright issues and all that, but for a moment let’s assume you can). Classically, the Minions are all yellow, so this is a property that should be at the class-level; in other words, a static property. So you might define the class as follows:

 
 
class ClassicMinion {
    public static $color = "yellow";
    public static function introduceYourself() {
        echo "I'm a " . self::$color . "-colored Minion!";
    }
}

Nice!

Now imagine that our game also has Minions that can talk clearly; we decide that these will be of blue color. But since they are primarily Minions, we don’t need to redefine the introduceYourself() method.

The new class might look like this:

 
 
class Minion2K extends ClassicMinion {
    public static $color = "blue";
}

And finally, it’s time to give this a spin:

 
 
Minion2K::introduceYourself();

And the output is: I’m a yellow-colored Minion.

WTF just happened?!!

Well, this is inheritance of static stuff in action. When the program runs, the call to self::$color resolves the base class, because self is always supposed to resolve to the class that contains the function. In this case the function comes from the ClassicMinion class, which is why we see a “yellow”.

The fix is startlingly simple, and equally startlingly reminiscent of bad naming conventions in PHP: static. The idea is to just replace the call self:: with static::, and PHP will calculate which class we’re actually talking about, like this:

 
 
public static function introduceYourself() {
    echo "I'm a " . static::$color . "-colored Minion!";
}

The binding of self, so to speak, will be figured out later when there is inheritance of static stuff. Hence the name:Late Static Binding.

And now we get the correct output: I’m a blue-colored Minion!

The choice of the keyword static is unfortunate, in my opinion; it adds confusion to an already too-messed-up language. But I digress. 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.