开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜