ぐらめぬ・ぜぷつぇんのはてダ(2007 to 2011)

2007年~2011年ごろまで はてなダイアリー に書いてた記事を引っ越してきました。

ApplicationControllerクラスと、その派生クラスの両方でそれぞれFilterを追加したい場合のTips

Akelosの各Controllerで共通となる基底クラス、ApplicationControllerでAというFilterを例えばbeforeFilter()で追加していたとします。で、ある一つのControllerでだけ、さらにBというFilterを追加したいとします。
app/application_controller.php :

<?php
//...
class ApplicationController extends AkActionController {
    //...
    function __construct() {
        $this->beforeFilter('_filter_func_1');
    }
    function _filter_func_1() {
        // ...
    }
    // ...
}

ここまではオッケーです。で、FooControllerにだけさらに追加したいとして・・・
app/controllers/foo_controller.php :

<?php
//...
class FooController extends ApplicationController {
    //...
    function __construct() {
        $this->beforeFilter('_filter_func_2');
    }
    function _filter_func_2() {
        // ...
    }
    // ...
}

としてしまうと、_filter_func_1()は呼ばれなくなるのでN.G.です。
これは単純にPHPのクラスを継承した場合のコンストラクタの問題で、FooControllerの__construct()の中で親クラス(ApplicationController)の__construct()を呼んでいないので、単純に_filter_func_1()が登録されない、というのが原因です。
というわけで解決も単純で、FooController#__constrct()のなかで親クラスのコンストラクタを呼べば良いだけです。
app/controllers/foo_controller.php :

<?php
//...
class FooController extends ApplicationController {
    //...
    function __construct() {
        $this->beforeFilter('_filter_func_2');
        parent::__construct();
    }
    // ...
}

親クラスコンストラクタを、処理の前で呼ぶか後で呼ぶかはお好みになると思います。

以上、あんまりPHPで凝ったクラスの継承関係を普段やってないため、うっかり嵌ったのでメモ。