tjtjtjのメモ

自分のためのメモです

多段継承したコントローラの依存コンポーネントを解決する

CakePHP1.3
コントローラを多段継承したとき、各コントローラーが依存するコンポーネントをそれぞれの $this->componentsに書くと、中間層コントローラのコンポーネントがロードされません。
依存するコンポーネントをAppControllerに指定してしまうと、使わないのにロードしてしまうのでロード時間分レスポンスが低下します。また子孫のコントローラーに指定すると、コントローラーの依存コンポーネントが不明確になるためメンテナンス性が低下します。
この問題はコントローラーが使用するコンポーネント、モデル、ヘルパに言えます。

問題

BaseController に依存した EntriesController を作りたいとき、次のように書くと BaseController で必要な BaseComp が生成されない。

コントローラークラスの依存関係
AppController <- BaseController <- EntriesController

class AppController extends Controller {
    public $components = array('AppComp');
}
class BaseController extends AppController {
    public $components = array('BaseComp');
}
App::import('Controller', 'Base');
class EntriesController extends BaseController {
    public $components = array('EntriesComp');
}

回避

中間層コントローラ(BaseController)が依存するコンポーネントをコンストラクタでマージする。

class AppController extends Controller {
    public $components = array('AppComp');
}
class BaseController extends AppController {
    private static $myComponents = array('BaseComp');
    public function __construct() {
        $this->components = am($this->components, self::$myComponents);
        parent::__construct();
    }
}
App::import('Controller', 'Base');
class EntriesController extends BaseController {
    public $components = array('EntriesComp');
}