CakePHP 3.x:在控制器上动态加载组件

CakePHP 3.x: loading components on the fly on controller

我正在尝试在控制器上动态加载组件。 该组件有一个 startup() 方法,我知道必须手动调用它,因为该组件已加载到操作中。

public function startup(\Cake\Event\Event $event) {
    //do something...
}

进入控制器:

$this->loadComponent('MyComponent');
$this->MyComponent->startup();

但是,这会产生警告,因为未传递 $event 参数。如何通过?

尝试通过 $this

$this->MyComponent->startup($this);

我认为这个话题解释了你的问题。

https://github.com/chronon/CakePHP-StripeComponent-Plugin/issues/4#issuecomment-30599742

解决方案正在通过 $this。谢谢

所以,进入控制器:

$this->loadComponent('MyComponent');
$this->MyComponent->startup($this);

根据当前动作加载组件

对于更简单且可能更不容易出错的事情,您可能需要考虑根据当前操作在控制器 initialize() 方法中加载组件,例如

if ($this->request->param('action') === 'theAction') {
    $this->loadComponent('TheComponent');
}

伪造控制器事件

我个人不建议这样做,但为了完整起见...

startup()Controller.startup 事件的回调。你可以很容易地伪造这个事件,但这可能不是一个好主意,因为对事件的操作不会产生与实际的、真正的控制器启动的事件相同的效果 Controller.startup 事件.见

\Cake\Controller\Controller::startupProcess()

结果正在派发过程中使用。因此,如果一个组件尝试 fiddle ,事情将没有任何效果,这可能会导致进一步的问题。

另外不要忘记还有 Controller.initialize 映射到 beforeFilter() 回调,当你加载这么晚的组件时,你也会错过那个回调。

因此请注意这些问题,以及可能需要在实际调用操作之前执行一些操作的组件可能产生的进一步副作用。考虑到这一点,下面是一个包含处理事件结果的基本示例。

$event = new \Cake\Event\Event('Controller.initialize', this);
$this->TheComponent->beforeFilter($event);
if ($event->result instanceof \Cake\Network\Response) {
    return $event->result;
}

$event = new \Cake\Event\Event('Controller.startup', this);
$this->TheComponent->startup($event);
if ($event->result instanceof \Cake\Network\Response) {
    return $event->result;
}