Late Static Binding Coming in PHP 5.3
Posted on 16th May 2009 by SameerBy far the most important change in PHP 5 was its much improved support for object oriented programming. It’s hard to imagine, but it was not so long ago when PHP did not offer support for basic object oriented necessities such as constructors, destructors, interfaces, abstract classes, public, private, magic methods, and so on.
Yet one of the most frustrating problems with PHP’s implementation of object oriented principles is the “self” keyword which is intended to reference methods and variables within a class in a static context.
class A {
public static function who() {
echo "this is A";
}
public static function test() {
self::who();
}
}
In the above code, calling A::test() calls A::who() and therefore outputs “this is A” because “self” resolves to “A”. Yet take a look at the code below (taken from PHP.net)
class A {
public static function who() {
echo "this is A";
}
public static function test() {
self::who();
}
}
class B extends A {
public static function who() {
echo "this is B";
}
}
B::test();
The above also outputs “this is A”.
For many people that is not the intended behavior. You are directly calling B::test() so because B inherits the test() method from A, you would expect that “self” would refer to B. However, PHP resolves “self” based on where the method is defined. Since the test() method is defined in A, any calls to “self” will reference A.
For the moment, I get around this problem by passing around the name of the child class:
class A {
public static function who() {
echo "this is A";
}
public static function test($classname) {
$classname::who();
}
}
class B extends A {
public static function who() {
echo "this is B";
}
}
B::test("B");
The above outputs “this is B”.
In PHP 5.3, the problem is resolved by introducing a new keyword “static”. Unlike self, static is capable of late static binding. In other words, PHP will realize that the method test() was inherited by B and a call to static::who() would resolve to B:who().
class A {
public static function who() {
echo "this is A";
}
public static function test() {
static::who();
}
}
class B extends A {
public static function who() {
echo "this is B";
}
}
B::test();
The above outputs “this is B”.
The functionality of self has not changed, so a call to self::who() would still resolve to A:who(). For more information check the PHP manual.

