我要做的是从当前班级的父母那里调用每个方法“init”。
我这样做是为了避免程序员每次在新控制器中创建init方法时都必须调用init方法(parent :: init())。
示例:
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 {}
正如您所看到的,init
方法不会调用父init
方法,但我希望我的应用(有一个选项)可以执行此操作。
因此,当我加载ControllerD
时,在调用它的init
方法之前(示例中没有,但应用程序测试它),我想调用每个父init
方法
听起来像这样:
parent::init(); // Controller C init
parent::parent::parent::init(); // Controller A init
所以我做了:
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 current 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');
}
}
}
这不起作用,因为ReflectionClass::isInstance
不接受其他参数而不是我们想要测试的对象(而不是像示例中那样表示它的ReflectionClass
对象)
**
只是:
我有一个对象$ x,我想调用$ x类的每个父类的init
方法。
**
有可能吗?
我希望我很清楚:)
由于
答案 0 :(得分:1)
ControllerB通过扩展ControllerA有一个init()
方法,所以你不必调用parent :: parent :: init()来从C获取A.你应该可以调用{{来自ControllerD的1}},它将调用ControllerC的parent::init()
方法。如果ControllerC调用init()
,它将调用ControllerA的parent::init()
方法。
如果您在被子类调用时尝试跳过Controller的特定init()
代码,则可以添加标记init()
,然后从较低的控制器调用function init($call_parent = false)
< / p>
答案 1 :(得分:0)
如果您没有静态使用这些类(从您的代码中没有说明static function
,我认为您不是),您是否尝试过使用__construct()
方法?在实例化类时会自动调用它,例如:
class MyClass {
public function __construct() {
echo 'Hello!';
}
}
$class = new MyClass();
这会自动输出'Hello!',但是如果扩展该类并且该子类包含__construct()
方法,则必须将parent::__construct()
放在childs构造方法中,但是你没有为每个父母做一次,只做一次,例如:
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();
那将输出“Hello!World!怎么样!”