我想做的是调用每个方法"init"从当前类的父母。
我这样做是为了避免程序员每次在新控制器中创建init方法时都必须调用init方法(parent::init())。
的例子:
class AspicController { } // main controller
class ControllerA extends AspicController { 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) {
// AspicController 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 AspicController extends a "Base class". Thus, we stopped at AspicController
*/
$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
方法。* *
可能吗?
我希望我说的很清楚:)
谢谢
ControllerB通过扩展ControllerA有一个init()
方法,所以你不应该调用parent::parent::init()来从c得到A。你应该可以从ControllerD调用parent::init()
,这将调用ControllerC的init()
方法。如果ControllerC调用parent::init()
,它将调用ControllerC的init()
方法。
如果你试图跳过控制器的特定init()
代码时,被子类调用,你可以添加一个标志function init($call_parent = false)
,然后,从较低的控制器,调用parent::init(true);
如果您没有静态地使用这些类(从您的代码中没有说明static function
,我认为您没有),您是否尝试过使用__construct()
方法?它在实例化类时被自动调用,例如:
class MyClass {
public function __construct() {
echo 'Hello!';
}
}
$class = new MyClass();
会自动输出'Hello!’,但是,如果您扩展类并且该子类包含__construct()
方法,则必须将parent::__construct()
放入子构造方法中,但是您不必对每个父类都这样做,只需一次,例如:
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!"世界!最近怎么样!"