CodeIgniterでRailsライクなbefore/afterフィルターを
CodeIgniterでRailsライクなbefore/afterフィルターを実現するライブラリを見つけたんでメモ。
導入
https://github.com/zackkitzmiller/codeigniter-filter
からファイルをダンロードし、
/config/hooks.phpの中身を/application/config/hooks.phpに追加。
/hooks/Filter.phpを/application/hooks/に移動。
以上で終了。
使い方
コントローラーのメンバ変数として$before_filterと$after_filerを定義する。ここにフィルターとして実行されるアクションとフィルターの適用対象を記述する。
actionだけを指定すればコントローラー内のすべてのpublicメソッドにフィルターが適用される。Railsのようにonly, exceptで適用対象を限定することも可能。
beforeフィルターはコントローラーのコンストラクタが呼ばれた直後に、afterフィルターはアクションが実行された直後に実行される。
<?php var $before_filter = array( 'action' => 'name_of_method_for_before_filter', 'except' => array('index', 'logout'); ); var $after_filter = array( 'action' => 'name_of_method_for_after_filter', 'except' => array('index', 'logout'); );
フィルターを複数指定することも可能。
<?php var $before_filter = array(); $before_filter[] = array( 'action' => 'before1', 'except' => array('index', 'logout'); ); $before_filter[] = array( 'action' => 'before2', 'except' => array('index', 'logout'); );
この時のフィルターの適用順序は、配列の先頭からとなる。
例
<?php class Test extends CI_Controller { var $before_filter = array(); var $after_filter = array(); function __construct() { parent::__construct(); $this->load->helper('url'); $this->before_filter[] = array( 'action' => '_before_filter_run', // 直接実行されないように、フィルタ用アクションはprivateにしておこう 'except' => array('home') ); $this->after_filter[] = array( 'action' => '_after_filter_run', 'only' => array('sent_away') ); } function index() { echo 'You made it to the index'; } function home() { echo 'This is home<br/>'; echo 'You may try going to the '.anchor('/test/index/', 'index'). ' of this controller.<br/>'; echo 'The before_filter will execute the before_filter_run method before the controller action is executed.<br/>'; echo 'It is demonstrated by having before_filter_run redirect to sent_away if the action is "index" <br/>'; } function sent_away() { echo "You've been sent here by the before_filter_run action, called by the before_filter!<br/>"; echo anchor('/test/home/', 'Click here to return to the test controller home'); } function _before_filter_run() { $filter = array('index'); if ( in_array($this->router->fetch_method(), $filter) ) { redirect('/test/sent_away/'); } else { return true; } } function _after_filter_run() { echo '<br/>This text is generated from the after_filter_run method'; } }