Manuel PHP
Late Static Bindings
As of PHP 5.3.0, PHP implements a feature called late static bindings which can be used to reference the called class in a context of static inheritance.
This feature was named "late static bindings" with an internal perspective in mind. "Late binding" comes from the fact that static:: will no longer be resolved using the class where the method is defined but it will rather be computed using runtime information. It was also called a "static binding" as it can be used for (but is not limited to) static method calls.
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:
Exemple #1 self:: usage
- <?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();
- ?>
L'exemple ci-dessus va afficher :
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.
Exemple #2 static:: simple usage
- <?php
- class A {
- public static function who() {
- echo __CLASS__;
- }
- public static function test() {
- static::who(); // Here comes Late Static Bindings
- }
- }
- class B extends A {
- public static function who() {
- echo __CLASS__;
- }
- }
- B::test();
- ?>
L'exemple ci-dessus va afficher :
Note: static:: does not work like $this for static methods! $this-> follows the rules of inheritance while static:: doesn't. This difference is detailed later on this manual page.
Exemple #3 static:: usage in a non-static context
- <?php
- class TestChild extends TestParent {
- public function __construct() {
- static::who();
- }
- public function test() {
- $o = new TestParent();
- }
- public static function who() {
- echo __CLASS__."\n";
- }
- }
- class TestParent {
- public function __construct() {
- static::who();
- }
- public static function who() {
- echo __CLASS__."\n";
- }
- }
- $o = new TestChild;
- $o->test();
- ?>
L'exemple ci-dessus va afficher :
Note: Late static bindings' resolution will stop at a fully resolved static call with no fallback. On the other hand, static calls using keywords like parent:: or self:: will forward the calling information.
Exemple #4 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();
- ?>
L'exemple ci-dessus va afficher :
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.
Exemple #5 Late static bindings inside magic methods
- <?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;
- ?>
L'exemple ci-dessus va afficher :
Remonter 
