从每个父类调用方法X


Calling method X from each parent

我想做的是调用每个方法"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方法。* *

可能吗?

我希望我说的很清楚:)

谢谢

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!"世界!最近怎么样!"