note 77698 added to function.get-class
| From: | dodgie74 at NOSPAM dot yahoo dot NOSPAM dot co dot uk | Date: | Sun, 09 Sep 2007 12:40:47 +0000 |
| Subject: | note 77698 added to function.get-class | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-130328@lists.php.net to get a copy of this message | ||
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()
{
//here, we want "self" to refer to the actual class, which might be a derived class that
inherits this method, not necessarily this base class
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.
----
Server IP: 69.147.83.197
Probable Submitter: 80.7.127.149
----
Manual Page -- http://www.php.net/manual/en/function.get-class.php
Edit -- https://master.php.net/note/edit/77698
Del: integrated -- https://master.php.net/note/delete/77698/integrated
Del: useless -- https://master.php.net/note/delete/77698/useless
Del: bad code -- https://master.php.net/note/delete/77698/bad+code
Del: spam -- https://master.php.net/note/delete/77698/spam
Del: non-english -- https://master.php.net/note/delete/77698/non-english
Del: in docs -- https://master.php.net/note/delete/77698/in+docs
Del: other reasons-- https://master.php.net/note/delete/77698
Reject -- https://master.php.net/note/reject/77698
Search -- https://master.php.net/manage/user-notes.php