I find having class variables useful for inherited classes, especially when inheriting abstract classes, yet self:: doesn't refer to the class calling the method, rather the actual class in which it was defined. Although it is less memory efficient, this can be circumvented with instance properties, but sometimes even this won't work, i.e., when using resources like class-wide database or prepared statement handles.
The pre-5.3.0 way that I used to get around this limitation was to write a class that stores a central value and sets instance properties as references to this value. In this way objects can have access to the same value while still being able to use inherited methods that reference this property.
Usage example:
<?php class Foo extends SharedPropertyClass {
public $foo = "bar";
public function showFoo() {
echo $this->foo, "\n";
}
}
class FooToo extends Foo {
public function __construct() {
$this->makeShared('foo');
}
}
$ojjo = new FooToo;
$ojjo->showFoo(); $xjjx = new FooToo;
$xjjx->showFoo(); $ojjo->foo = "new";
$ojjo->showFoo(); $xjjx->showFoo(); ?>
Notice how the showFoo() method, while defined in the parent class, correctly uses the child class's "foo" property (unlike self:: would), and how the "foo" property is shared by all instances of FooToo objects (like a static property). This is essentially how the new static:: keyword will work, and how most people probably expected the self:: keyword to work.
<?php
abstract class SharedPropertyClass {
private static $shared = array();
public function makeShared($property) {
$class = get_class($this);
if (!property_exists($this,$property))
trigger_error("Access to undeclared property "
. "'$property' in class $class.",E_USER_ERROR);
if (!array_key_exists($class,self::$shared))
self::$shared[$class] = array();
if (!array_key_exists($property,self::$shared[$class]))
self::$shared[$class][$property]
= isset($this->$property)
? $this->$property
: null;
$this->$property =& self::$shared[$class][$property];
}
public function isShared($property) {
$class = get_class($this);
if (!property_exists($this,$property))
trigger_error("Access to undeclared property "
. "'$property' in class $class.",E_USER_ERROR);
return array_key_exists($class,self::$shared)
&& array_key_exists($property, self::$shared[$class]);
}
}
?>