Here is a small workaround I made for the static inheritance issue. It's not perfect, but it works.
<?php
class BaseClass {
protected static $nextStatic = false;
protected static function getStatic() {
if (self::$nextStatic) {
$class = self::$nextStatic;
self::$nextStatic = false;
return $class;
}
$backTrace = debug_backtrace();
$class = false;
for ($i=0; $i<count($backTrace); $i++) {
if (isset($backTrace[$i]['class'])) {
if (!in_array($backTrace[$i]['class'], array('BaseClass', 'GenericClass'))) {
return $backTrace[$i]['class'];
} else {
$class = $backTrace[$i]['class'];
}
} else {
return $class;
}
}
return $class;
}
public static function setNextStatic($class) {
self::$nextStatic = $class;
}
}
class GenericClass extends BaseClass {
public static $name = 'Generic';
public function getName() {
$static = get_class_vars(get_class($this));
return $static['name'];
}
public static function basicClassName() {
return self::$name;
}
public static function staticClassName() {
$staticName = self::getStatic();
$static = get_class_vars($staticName);
return $static['name'];
}
}
class SomeClass extends GenericClass {
public static $name = 'Some';
public static function returnClassNameWith($string) {
return $string.' : '.self::staticClassName();
}
}
$a = new SomeClass();
echo 'Name of $a : '.$a->getName().'<br />';
echo 'Basic call to SomeClass::$name : '.SomeClass::basicClassName().'<br />';
echo 'Global call to SomeClass::$name : '.SomeClass::staticClassName().'<br />';
BaseClass::setNextStatic('SomeClass');
echo 'Global call to SomeClass::$name with pre-set : '.SomeClass::staticClassName().'<br />';
echo 'Internal call to SomeClass::$name : '.SomeClass::returnClassNameWith('This is a ').'<br />';
?>
There are two issues with this workaround :
- if you call a static method from global env, you need to declare the name of the class BEFORE calling the method, otherwise the workaround won't work (see 3rd and 4th examples). But I assume good programming makes few calls to static methods from global scope, so this shouldn't be long to fix if you use it.
- the workaround fails to access to private or protected static vars, as it uses get_class_vars(). If you find any better solution, let us know.
With Php 5.3.0, upgrading will be easy : just delete the methods from the basic class, and search/replace any call to getStatic() and setNextStatic() by static:: - or one could use a selector on PHP_VERSION value to include either the BaseClass file with workaround or a BaseClass file using static::