Clearing Up Some Annoying PHP Static
While on vacation I started some prep work for using MongoDB at DailyLit, which is mostly written in PHP. The prep work consists of creating a lightweight way of getting PHP objects in and out of MongoDB (I know there are some things out there already, but what’s the fun in that?).
Here is a slightly simplified summary what I am shooting for:
class Fruit extends mdbObject { } // provides all the DB functionality
class Apple extends Fruit { }
$a = new Apple();
$a->mdbInsert(); // insert this instance into the DB
$b = Apple::mdbFindOne(); // get an apple object from the DB
$c = Fruit::mdbFindOne(); // this might be get an Apple or a Banana
I like the idea of using static/class methods for retrieval because these will be generating one or more objects and I do not want to have to deal with separate factory or builder classes. Unfortunately, I encountered some annoying PHP static:
class Fruit {
public static function test() {
echo __CLASS__;
}
}
class Apple extends Fruit {
}
Apple::test();
This prints “Fruit” — what the flagnard? For my plan to work, I need this to print “Apple”.
First, lets establish that “Apple” is not an unreasonable expectation. In Python, I can do the following:
class Fruit:
@classmethod
def test(c):
print c
class Apple(Fruit):
pass
Apple.test()
This prints “Apple” (well, actually it prints “__main__.Apple”).
In Ruby, I can do this:
class Fruit
def self.test
puts self.name
end
end
class Apple<Fruit
end
Apple.test()
That also prints “Apple”, which suggests that my expectation for the PHP code was reasonable.
Second, is there a solution in PHP? I started to poke around a bit more and discovered “Late Static Bindings.” The documentation starts very promising:
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.
I was, however, taken aback by the examples on that page, which seemed to suggest that in order to get the right version of __CLASS__ you had to actually implement a static method in the derived class that would then be called by the base class, which is exactly what I was trying to avoid in the first place.
Only by reading through the user comments did I discover that there is now also a new function get_called_class() that provides the solution:
class Fruit {
public static function test() {
echo get_called_class();
}
}
class Apple extends Fruit {
}
Apple::test();
That will print “Apple” (assuming you are running PHP 5.3.0). It is amazing to me that this only got fixed now. Then again namespaces only just arrived in that version, so maybe I shouldn’t have been surprised.
Posted: 27th August 2009 – Comments

![Reblog this post [with Zemanta]](http://img.zemanta.com/reblog_e.png?x-id=3e9c6070-b426-4c7b-a8ce-da9659d26818)