开发者

Calling method X from each parent

what i'm trying to do is call each method "init" from current class's parents.

I'm doing that to avoid programmers to have to call init method (parent::init()) each time they create an init method in a new controller.

Example:

class Aspic\Controller { } // main controller
class ControllerA extends Aspic\Controller { public function init() {/* do something 1 */}  
class ControllerB extends ControllerA {}
class ControllerC extends ControllerB { public function init() { /* do something 2 */ }
class ControllerD extends ControllerC {}

As you can see the init methods do not call parent init method but i want my app (there is an option) do it.

Thus when I'm loading ControllerD, before calling it's init method (there isn't in the example but the app test it), i want to call each parent init method.

sound like this:

parent::init(); // Controller C init
parent::parent::parent::init(); // Controller A init

So i did :

if($this->_autoCallParentsInit) {
    // Aspic\Controller is the main controller, which is the mother of all others
    $aspicControllerRc = new \ReflectionClass('Aspic\\Controller');
    $rc = new \ReflectionClass($this); // We are in D
    $currPrefix = '';

    // Calling each init methods of curre开发者_Python百科nt class parent
    // Avoid using parent::init() in each controller
    while(($parentClass = $rc->getParentClass()) AND $aspicControllerRc->isInstance($parentClass)) {
        /* 
        $aspicControllerRc->isInstance($parentClass)
        => because Aspic\Controller extends a "Base class". Thus, we stopped at Aspic\Controller
        */

        $currPrefix .= 'parent::';

        // Must have explicit method (not inherited from parent) BUT actually hasMethod does not care
        if($parentClass->hasMethod('init')) {
            call_user_func($currPrefix.'init');                     
        }
    }
}

This is not working because ReflectionClass::isInstance does not accept others argument than the object we want to test (and the not a ReflectionClass object representing it as in the example)

** Simply: I have an object $x, and i want to call the init method of each parent of the class of $x. **

Is it possible ?

I hope i was clear :)

Thanks


ControllerB has an init() method by virtue of extending ControllerA, so you shouldn't have to call parent::parent::init() to get to A's from C. You should be fine to call parent::init() from ControllerD, which will call ControllerC's init() method. If ControllerC calls parent::init() it will be calling ControllerA's init() method.

If you're trying to skip the Controller's specific init() code when being called by a subclass, you could add a flag function init($call_parent = false) and then, from lower controllers, call parent::init(true);


If you're not using the classes statically (which, from your code not stating static function, I assume you're not), have you tried using the __construct() method? It gets automatically called when you instantiate the class, for example:

class MyClass {
  public function __construct() {
    echo 'Hello!';
  }
}

$class = new MyClass();

That will automatically output 'Hello!', however if you extend the class and that child class contains a __construct() method you will have to put parent::__construct() inside the childs construct method, however you wont have to do it for every parent, just the once, for example:

class MyClassB extends MyClass {
  public function __construct() {
    parent::__construct();
    echo 'World!';
  }
}

class MyOtherClass extends MyClassB
  public function __construct() {
    parent::__construct();
    echo 'How\'s it going!';
  }
}

$class = new MyOtherClass();

That will output "Hello! World! How's it going!"

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜