anon
anon

Reputation:

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 to 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?

Upvotes: 3

Views: 3814

Answers (4)

Mohammed Jebrini
Mohammed Jebrini

Reputation: 13

Using static::CONSTNAME will return the right value.

Upvotes: 1

Ben
Ben

Reputation: 21249

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

Upvotes: 1

mario
mario

Reputation: 145482

I believe the according syntactic salt for your case is:

print constant(get_class($this)."::NAME");

Upvotes: 5

Hamish
Hamish

Reputation: 23316

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.

Upvotes: 9

Related Questions