As noted in bug #30934 (which is not actually a bug but a consequence of a design decision), the "self" keyword is bound at compile time. Amongst other things, this means that in base class methods, any use of the "self" keyword will refer to that base class regardless of the actual (derived) class on which the method was invoked. This becomes problematic when attempting to call an overridden static method from within an inherited method in a derived class. For example:
<?php
class Base
{
protected $m_instanceName = '';
public static function classDisplayName()
{
return 'Base Class';
}
public function instanceDisplayName()
{
return $this->m_instanceName . ' - ' . self::classDisplayName();
}
}
class Derived extends Base
{
public function Derived( $name )
{
$this->m_instanceName = $name;
}
public static function classDisplayName()
{
return 'Derived Class';
}
}
$o = new Derived('My Instance');
echo $o->instanceDisplayName();
?>
In the above example, assuming runtime binding (where the keyword "self" refers to the actual class on which the method was invoked rather than the class in which the method is defined) would produce the output:
My Instance - Derived Class
However, assuming compile-time binding (where the keyword "self" refers to the class in which the method is defined), which is how php works, the output would be:
My Instance - Base Class
The oddity here is that "$this" is bound at runtime to the actual class of the object (obviously) but "self" is bound at compile-time, which seems counter-intuitive to me. "self" is ALWAYS a synonym for the name of the class in which it is written, which the programmer knows so s/he can just use the class name; what the programmer cannot know is the name of the actual class on which the method was invoked (because the method could be invoked on a derived class), which it seems to me is something for which "self" ought to be useful.
However, questions about design decisions aside, the problem still exists of how to achieve behaviour similar to "self" being bound at runtime, so that both static and non-static methods invoked on or from within a derived class act on that derived class. The get_class() function can be used to emulate the functionality of runtime binding for the "self" keyword for static methods:
<?php
class Base
{
protected $m_instanceName = '';
public static function classDisplayName()
{
return 'Base Class';
}
public function instanceDisplayName()
{
$realClass = get_class($this);
return $this->m_instanceName . ' - ' . call_user_func(array($realClass, 'classDisplayName'));
}
}
class Derived extends Base
{
public function Derived( $name )
{
$this->m_instanceName = $name;
}
public static function classDisplayName()
{
return 'Derived Class';
}
}
$o = new Derived('My Instance');
echo $o->instanceDisplayName();
?>
Output:
My Instance - Derived Class
I realise that some people might respond "why don't use just just the class name with ' Class' appended instead of the classDisplayName() method", which is to miss the point. The point is not the actual strings returned but the concept of wanting to use the real class for an overridden static method from within an inherited non-static method. The above is just a simplified version of a real-world problem that was too complex to use as an example.
Apologies if this has been mentioned before.