1

The comments in the following code show what I am trying to accomplish, which is something very simple: I want to be able to refer to the name of the parent class using a PHP built-in constant (or other construct) such as __CLASS__, but which refers to the parent class rather than the current class (e.g. parent::__CLASS__) (also, while the code does not show it, if I have a subsubclass, then within such class I want to be able to refer t the parent class via something like parent::parent::__CLASS__ if at all possible).

class ParentClass {

  protected $foo;

  function __construct() {

    $this->foo = "hello";

  }

}

class DerivedClass extends ParentClass {

  public $bar;

  public $baz;

  function __construct($bar) {

    // I want to be able to write
    // something like parent:__CLASS__
    // here in place of 'ParentClass'
    // so that no matter what I rename
    // the parent class, this line will
    // always work. Is this possible?

//      if (is_a($bar, parent::__CLASS__)) {

    if (is_a($bar, 'ParentClass')) {

      $this->bar = $bar;

    } else {

      die("Unexpected.");

    }

    $this->baz = "world";

  }

  public function greet() {

    return $this->bar->foo . " " . $this->baz;

  }

}

$d = new DerivedClass(new ParentClass());
echo $d->greet();

OUTPUT:

hello world
John Sonderson
  • 3,238
  • 6
  • 31
  • 45
  • 1
    If I understood that right I don't understand why you would ever need such a messy construct. Try to describe what real problem you try to solve with that. – floriank Feb 08 '15 at 23:24
  • 2
    Did you try http://php.net/manual/en/function.get-parent-class.php ? – MikeWu Feb 08 '15 at 23:26
  • @burzum, subclasses often need to reference instances of parent classes for several reasons. The code I provided is just for illustrative purposes. – John Sonderson Feb 09 '15 at 00:06
  • @MikeWu, as pointed out below, get_parent_class() is the best solution for all of the given reasons. – John Sonderson Feb 09 '15 at 00:06
  • @John Sonderson I would consider dependency injection in this case. IMHO your example isn't a good solution because it introduces pretty tight coupling between the classes. – floriank Feb 09 '15 at 00:13
  • Fair enough, perhaps your observation is a good one: when iterating over instances of the parent class, you will have to check if an instance is an instance of a derived class before calling any of its methods if that is what you want. But there are also other less obvious use cases as well, and in such cases it may be ok to do the above. For instance, consider a separate iterator chain for links to parent class instances,: not hard to imagine, just think of data structures. Since the iterator chains are separate, you don't get tight coupling, you get loose coupling in the described case. – John Sonderson Feb 09 '15 at 00:45

2 Answers2

1

You need get_parent_class Function to do it.

function __construct($bar) {

    $parent = get_parent_class($this);


    if (is_a($bar, $parent)) {

      $this->bar = $bar;

    } else {

      die("Unexpected.");

    }

    $this->baz = "world";

  }

if you need further level down you can use:

class subDerivedClass extents DerivedClass{
    $superParent = get_parent_class(get_parent_class($this));
}
Nishanth Matha
  • 5,993
  • 2
  • 19
  • 28
1

In PHP 5.5, you can use the keyword ::class to retrieve the name of a class' parent, but it will only work a) from within the class and b) only one level up, that is the immediate parent ancestor:

function __construct($bar) {
   if ($bar instanceof parent::class) {
      ...
   }
}

Best solution I'd go for is chaining get_parent_class:

if ($bar instanceof get_parent_class(get_parent_class())) {
    ...
}

Or method chaining through reflection:

$parent_class = (new Reflection($this))->getParentClass()->getParentClass()->getName();

if ($bar instanceof $parent_class) {
    ...
}
silkfire
  • 24,585
  • 15
  • 82
  • 105
  • That's three ways to do it. Nice to know all the details. I think `get_parent_class` is the most straightforward solution. Thanks. – John Sonderson Feb 09 '15 at 00:08