elite5472
elite5472

Reputation: 2184

Traverse a class tree without overriding methods?

I have the following:

class A
{
    public function getDependencies()
    {
        //returns A.default.css, A.default.js, A.tablet.css, A.tablet.js, etc,
        //depending on what files exist and what the user's device is.
    }
}

In class B, which extends A, if I call getDependencies I will get things like: B.default.css, B.default.js and so on.

What I want to do now is include the results of A as well, without having to override getDependencies() in B. In fact, I'm not even sure if overriding would work, at all. Is this possible?

This is for dynamic CSS/JS loading for templates, and eventually compilation for production as well.

EDIT= I should point out that what getDependencies returns is dynamically generated, and not a set of stored values.

EDIT2= The idea I have is that just inheriting from A will provide the behavior. I probably need some kind of recursion that goes through the hierarchy tree, starting from B, to B's parent, and all the way up to A, without any method overriding happening along the way.

Upvotes: 0

Views: 123

Answers (3)

elite5472
elite5472

Reputation: 2184

It's pretty easy using the reflection API.

I can simply iterate through the parent classes:

$class = new \ReflectionClass(get_class($this));
while ($parent = $class->getParentClass()) 
{
        $parent_name = $parent->getName();
        // add dependencies using parent name.
        $class = $parent;
}

Credits to ComFreek who pointed me to the right place.

Upvotes: 1

ComFreek
ComFreek

Reputation: 29414

Use parent::getDependencies(), e.g.:

class B
{
  public function getDependencies()
  {
    $deps = array('B.style.js' 'B.default.js', 'B.tables.js' /*, ... */);
    // merge the dependencies of A and B
    return array_merge($deps, parent::getDependencies());
  }
}

You can also try this code which uses ReflectionClass in order to iterate over all parents:

<?php

class A
{
  protected static $deps = array('A.default.js', 'A.tablet.js');
  public function getDependencies($class)
  {
    $deps = array();

    $parent = new ReflectionClass($this);

    do 
    {
      // ReflectionClass::getStaticPropertyValue() always throws ReflectionException with
      // message "Class [class] does not have a property named deps"
      // So I'm using ReflectionClass::getStaticProperties()

      $staticProps = $parent->getStaticProperties();
      $deps = array_merge($deps, $staticProps['deps']);
    }
    while ($parent=$parent->getParentClass());

    return $deps;
  }
}
class B extends A
{
  protected static $deps = array('B.default.js');
}

class C extends B
{
  protected static $deps = array('C.default.js');
}

$obj = new C();
var_dump( $obj->getDependencies($obj) );

On Ideone.com

Upvotes: 2

Bogo
Bogo

Reputation: 688

You can use self keyword - this will returns A class values and then you can use $this to get the B class values.

Upvotes: 0

Related Questions