Late Static Bindings
Posted on March 27th, 2009 by SamPHP 5.3 implements a feature called “late static bindings” that has been in the works since the PHP Developers Meeting that took place in November 2005 in Paris. This feature resolves an issue of inheritance, used to reference the called class in a context of static inheritance. Prior to version 5.3 a problem existed if the class was extended and a call was from the child class, “late static binding” alleviates this issue. The name is in reverence to the internal process, late bindings are computed using runtime information; as opposed to being resolved using the class where the method was defined.
Limitations of self::
Static references to the current class like self:: or __CLASS__ are resolved using the class in which the function belongs, as in where it was defined; while static:: is resolved as to what class was called.
<?php class A { public static function who() { echo __CLASS__; } public static function test() { self::who(); } } class B extends A { public static function who() { echo __CLASS__; } } B::test(); // A ?>
Late Static Bindings’ usage
Late static bindings tries to solve that limitation by introducing a keyword that references the class that was initially called at runtime. Basically, a keyword that would allow you to reference B from test() in the previous example. It was decided not to introduce a new keyword but rather use static that was already reserved.
<?php class A { public static function who() { echo __CLASS__; } public static function test() { static::who(); } // Late Static Bindings } class B extends A { public static function who() { echo __CLASS__; } } B::test(); // B ?>
static:: usage in a non-static context
<?php class A { public function __construct() { static::who(); } public static function who() { echo __CLASS__."n"; } } class B extends A { public function __construct() { static::who(); } public function test() { $o = new A(); } public static function who() { echo __CLASS__."n"; } } $o = new B; $o->test(); // B // A ?>
Forwarding and non-forwarding calls
<?php class A { public static function foo() { static::who(); } public static function who() { echo __CLASS__."n"; } } class B extends A { public static function test() { A::foo(); parent::foo(); self::foo(); } public static function who() { echo __CLASS__."n"; } } class C extends B { public static function who() { echo __CLASS__."n"; } } C::test(); // A // C // C ?>
Edge cases
There are lots of different ways to trigger a method call in PHP, like callbacks or magic methods. As late static bindings base their resolution on runtime information, it might give unexpected results in so-called edge cases.
<?php class A { protected static function who() { echo __CLASS__."n"; } public function __get($var) { return static::who(); } } class B extends A { protected static function who() { echo __CLASS__."n"; } } $b = new B; $b->foo; // B ?>
You can find more information on the PHP manual page for Late Static Bindings.




![Validate my RSS feed [Valid RSS]](http://php-phreaks.com/wp-content/themes/php-Phreaks/imgs/valid-rss.png)
Leave a Reply