BlaBla.cn

Late Static Bindings


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:

Example #1 self:: usage

<?php
class  {
    public static function 
who () {
        echo 
__CLASS__ ;
    }
    public static function 
test () {
        
self :: who ();      
    }  
}  

class 
extends  {      
    public static function 
who () {
         echo 
__CLASS__ ;
    }  
}   

B :: test ();
?>

The above example will output:

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.

Example #2 static:: simple usage

<?php
class  {
    public static function 
who () {
        echo 
__CLASS__ ;
    }
    public static function 
test () {
        static::
who ();  // Here comes Late Static Bindings     
    
}  
}  

class 
extends  {      
    public static function 
who () {
         echo 
__CLASS__ ;
    }  
}   

B :: test ();
?>

The above example will output:

B

    

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.

Example #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 ();

?>

The above example will output:

TestChild
TestParent

    

Note: Late static bindings' resolution will stop at a fully resolved static call with no fallback.

Example #4 Fully resolved static calls

<?php
class  {
    public static function 
foo () {
        static::
who ();
    }
        
    public static function 
who () {
        echo 
__CLASS__ . "\n" ;
    }
}

class 
extends  {
    public static function 
test () {
        
A :: foo ();
    }

    public static function 
who () {
        echo 
__CLASS__ . "\n" ;
    }
}

B :: test ();
?>

The above example will output:

A

     

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.

Example #5 Late static bindings inside magic methods

<?php
class  {

   protected static function 
who () {
        echo 
__CLASS__ . "\n" ;
   }

   public function 
__get ( $var ) {
       return static::
who ();
   }
}

class 
extends  {

   protected static function 
who () {
        echo 
__CLASS__ . "\n" ;
   }
}

$b  = new  B ;
$b -> foo ;
?>

The above example will output:

B

    

 
BlaBla.cn

© 2005-2008 BlaBla.cn 版权所有