How can I create a constant in a subclass to be used in a method found in a parent class in PHP 5.2?
Edit:
*Note: I'm using PHP 5.2 for the time being, unfortunately. I can't find a decent cheap host offering 5.3...In PHP, self
refers to the class in which the called method is defined. This means that if you don't override a method in the child class, the keyword self
will refer to the parent class, even when called from the child.
For example, this code:
<?php
class ParentClass {
const NAME = "ParentClass";
public function showName() {
echo self::NAME . "<br />\n";
}
}
class ChildClass extends ParentClass {
const NAME = "ChildClass";
public function __construct() {
echo self::NAME . "<br />\n";
}
}
$test = new ChildClass();
$test->showName();
?>
Will create this output:
ChildClass
ParentClass
What I want to do is to create a default method (e.g. showName()
in the example above) which exists in a parent class with constants defining default values to use. In the child, I want t开发者_如何学Co be able to override these constants (note the const
in the child definition above), and have those values be used when I call the method on an instance of the child.
In short, how can I make it so that the output of the above sample would be...
ChildClass
ChildClass
...without having to duplicate the code of the parent within the child?
Try
function showName() {
return static::NAME;
}
This uses late static binding:
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.
More precisely, late static bindings work by storing the class named in the last "non-forwarding call". In case of static method calls, this is the class explicitly named (usually the one on the left of the :: operator); in case of non static method calls, it is the class of the object. A "forwarding call" is a static one that is introduced by self::, parent::, static::, or, if going up in the class hierarchy, forward_static_call(). The function get_called_class() can be used to retrieve a string with the name of the called class and static:: introduces its scope.
EDIT: For 5.2.x
If you don't have 5.3.0 you won't be able to take advantage of this. One common hack solution is to create a static cache (e.g. private static $statics = array()
) referenced by child class name. It requires you to track object inheritance to override the value on __construct, and to explicitly define which statics are 'inheritable'. For example, SilverStripe uses this technique in the Sapphire ORM to get around PHP static binding limitations. They define a base Object class, and various static var management functions.
I believe the according syntactic salt for your case is:
print constant(get_class($this)."::NAME");
Maybe it's just because of your short example but the "self" referencing doesn't seem needed.
I would just do this:
class ParentClass {
public function showName() {
echo $this->name() . "<br />\n";
}
public static function name() {
return "ParentClass";
}
}
class ChildClass extends ParentClass {
public function __construct() {
echo $this->name() . "<br />\n";
}
public static function name() {
return "ChildClass";
}
}
$test = new ChildClass();
$test->showName();
Output:
ChildClass
ChildClass
Using static::CONSTNAME
will return the right value.
精彩评论