PHPでFilterChainを実装してみた
説明
前処理と後処理を各FilterClassに実装してFilterをChainさせます。
処理の順番としては
■前処理(prefilter)
filterA → filterB → filterC
■後処理(postfilter)
filterC → filterB → filterA
というように後処理は前処理と逆に行われます。
FilterChainクラス
<?php class FilterManager { private static $_filters = array(); private static $_index = 0; private function __construct(){} public function build( array $filters ) { foreach( $filters as $filter ) { $filter_name = ucfirst( $filter ) . 'Filter'; $file_name = $class_name . '.php'; //require_once( './Filter.php' ); require_once( $file_name ); self::add( $filter_name ); } } static private function add( $filter ) { self::$_filters[] = $filter; } static public function execute() { // prefilter foreach( self::$_filters as $filter ) { $filter::prefilter(); ++self::$_index; } // postfilter foreach( array_reverse( self::$_filters ) as $filter ) { $filter::postfilter(); --self::$_index; } } static public function getCurrentFilter() { return self::$_filters[ self::$_index ]; } }
FIlterChainを構築するbuildメソッド
FilterChainにFilterを追加するaddメソッド
FilterChainを実行するexecuteメソッド
現在実行中のFilterを取得するgetCurrentFilterメソッド
を定義します。
Filterのinterface
<?php interface Filter { static public function prefilter(); static public function postfilter(); }
prefilter,postfilterのメソッドを定義します。
各Filterの定義
<?php class ViewFilter implements Filter { static public function prefilter() { echo "View Prefilter \n"; } static public function postfilter() { echo "View Postfilter \n"; } } class ActionFilter implements Filter { static public function prefilter() { echo "Action Prefilter \n"; } static public function postfilter() { echo "Action Postfilter \n"; } }
本来はprefilter,postfilterにそれぞれ的確な内容を記述すべきですが、
今はサンプルなので適当にechoだけ書いておきます。
client
<?php /* client */ require_once( './FilterManager.php' ); //呼び出しfilterの決定 $filters = array( 'view', 'action' ); //filterのbuildと実行 FilterManager::build( $filters ); FilterManager::execute();
FilterChainを実行してくれるFilterManagerを呼び出し、配列形式で利用したいFilterクラス名を渡します。
実行結果
View Prefilter Action Prefilter Action Postfilter View Postfilter
prefilterとpostfilterの実行の順番が逆になっていることが分かります。