Late Static Binding: a practical example

by Sean Coates (2008-02-12)
  Page: 1  2  [next]

Late Static Binding (LSB) is a topic that's been brought up numerous times in the past three years in various PHP development discussion circles (and we're finally getting it in PHP 5.3)—but what does it really do, and why should you care? Here's a simple practical example of how it can greatly simplify your code's design.

In the now-infamous PHP Developers Meeting that took place in November 2005 in Paris, the topic of late static binding was officially discussed by the core team; although they agreed to implement it, as with many topics on that meeting's agenda, the details were left open for discussion.

Now, over 2 years since it was officially recognized as an upcoming feature, late static binding will finally become available to end users in PHP 5.3. This is great news, but it hasn't seen much publicity in the user side of the PHP community, except as an excellent manual entry.

Simply put, the new late static binding functionality allows objects to inherit methods from parent classes as before, but enables inherited methods to access static constants, methods and properties of the inherited class, and not only of the parent class. This is best illustrated in code:

  1. class Beer {
  2.     const NAME = 'Beer!';
  3.     public function getName() {
  4.         return self::NAME;
  5.     }
  6. }
  7. class Ale extends Beer {
  8.     const NAME = 'Ale!';
  9. }
  10. $beerDrink = new Beer;
  11. $aleDrink = new Ale;
  12. echo "Beer is: " . $beerDrink->getName() ."\n";
  13. echo "Ale is:  " . $aleDrink->getName()  ."\n";

This code outputs:

  1. Beer is: Beer!
  2. Ale is:  Beer!

As you can see, the Ale class inherits the getName() method, but self still points at the class in which it was used (the Beer class). This remains true in PHP 5.3, but a new keyword has been added: static.

Again, this can be described with some simple code:

  1. <?php
  2.  
  3. class Beer {
  4.     const NAME = 'Beer!';
  5.     public function getName() {
  6.         return self::NAME;
  7.     }
  8.     public function getStaticName() {
  9.         return static::NAME;
  10.     }
  11. }
  12.  
  13. class Ale extends Beer {
  14.     const NAME = 'Ale!';
  15. }
  16.  
  17. $beerDrink = new Beer;
  18. $aleDrink = new Ale;
  19.  
  20. echo "Beer is: " . $beerDrink->getName() ."\n";
  21. echo "Ale is:  " . $aleDrink->getName()  ."\n";
  22.  
  23. echo "Beer is actually: " . $beerDrink->getStaticName() ."\n";
  24. echo "Ale is actually:  " . $aleDrink->getStaticName()  ."\n";

This new keyword, static instructs the code to use the inherited class' constant, instead of the constant of the class where the getStaticName() method was defined. static has to be introduced due to the added functionality, and for backwards-compatibility—self still works like it has in previous versions of PHP.

Internally, the main difference (and the reason this is called late binding) between these two types of access is that PHP determines the value of self::NAME at compile time (when the PHP tokens are turned into opcodes that are to be interpreted by the Zend Engine), and it determines the value of static::NAME at runtime (when those opcodes are actually processed by the Zend Engine).

With this new tool in hand, let's see how it can improve some existing code.

File under: art  homepage  late static bindings  lsb  PHP 5.3 
  Page: 1  2  [next]

Comments

There are no comments on this entry.

Visit the forum