📚

CakePHPでComponentの読み込み箇所について

2021/12/01に公開

Cookbookに記載されていますがコンポーネントをロードするには使っているコントローラーのinitialize()メソッド内で loadComponent() を使用しないといけません。

public function initialize()
{
	parent::initialize();
        $this->loadComponent('RequestHandler', [
            'viewClassMap' => ['json' => 'AppJsonView'],
        ]);
        $this->loadComponent('Security', ['blackholeCallback' => 'blackhole']);
}

ですが、必ずinitialize()メソッド内で loadComponent() を使用する必要があるとは思っておらず、initialize()メソッドをつくらずにアクション内でloadComponent()を使用した結果コンポーネントが動作しないということがありました。
なので、そのときに調べたことをまとめたいと思います。

https://book.cakephp.org/4/ja/controllers/components.html

動作確認時の環境
CakePHP:4.2.8
cakephp/authentication: 2.6.1


authenticationプラグインを例にします

Controllerのアクションが読み込まれる前にController.phpのstartupProcess()が呼ばれれ、そこでinitialize()メソッド、staratup()メソッドの順番で呼ばれます。

Controller.php
    public function startupProcess(): ?ResponseInterface
    {
        $event = $this->dispatchEvent('Controller.initialize');
        if ($event->getResult() instanceof ResponseInterface) {
            return $event->getResult();
        }
        $event = $this->dispatchEvent('Controller.startup');
        if ($event->getResult() instanceof ResponseInterface) {
            return $event->getResult();
        }

        return null;
    }

AuthenticationComponentのstartup()で認証のチェックが行われていますが、
initialize()でloadComponent('Authentication.Authentication')をしていないと
startup()が実行されません。
その結果認証機能がうまく動作せずアクションの内容が実行されるということが起きてしまいます。

AuthenticationComponent.php
public function startup(): void
{
    if ($this->getConfig('identityCheckEvent') === 'Controller.startup') {
        $this->doIdentityCheck();
    }
}

Discussion