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!"
精彩评论