Yii 1.x 過濾器可在控制器動作執行前/後介入,支援多重過濾器鏈,可中斷執行。定義於控制器 filters() 方法回傳的陣列中。
控制器內定義 filter 方法,接收 $filterChain 參數:
class UserController extends CController {
public function filters() {
return array(
'addFilter + add', // 套用至 add 動作
);
}
public function filterAddFilter($filterChain) {
echo "方法型過濾器執行前
";
$filterChain->run(); // 繼續執行後續過濾器與動作
echo "方法型過濾器執行後
";
}
public function actionAdd() {
echo "actionAdd 執行
";
}
}
繼承 CFilter,覆寫 preFilter()、postFilter():
class TestFilter extends CFilter {
protected function preFilter($filterChain) {
echo "-->TestFilter.preFilter
";
return true; // false 可阻止動作執行
}
protected function postFilter($filterChain) {
echo "-->TestFilter.postFilter
";
}
}
在控制器註冊:
public function filters() {
return array(
array('application.filters.TestFilter + create'), // 套用至 create
);
}
測試場景:SiteController 同時掛載方法型 AccessControl 與類別型 MyFilter
public function filters() {
return array(
'AccessControl - create', // 排除 create
array('application.filters.MyFilter + create'),
);
}
site/print:filterAccessControl → actionPrintsite/create:MyFilter.preFilter → actionCreate → MyFilter.postFilter若同時套用兩者:
public function filters() {
return array(
'AccessControl - create',
array('application.filters.MyFilter + create,print'),
);
}
site/print:filterAccessControl → MyFilter.pre → actionPrint → MyFilter.postclass CFilter extends CComponent implements IFilter {
public function filter($filterChain) {
if ($this->preFilter($filterChain)) {
$filterChain->run();
$this->postFilter($filterChain);
}
}
protected function preFilter($filterChain) { return true; }
protected function postFilter($filterChain) { }
}
關鍵點:preFilter 回傳 false 可阻斷動作與後續過濾器。
+ action1, action2:僅套用列出動作- action1, action2:排除列出動作| Yii 1.x | Yii 2 | 說明 |
|---|---|---|
filters() 方法 | behaviors() 方法 | 過濾器本質為行為 |
方法型 filterXxx() | 繼承 ActionFilter 覆寫 beforeAction/afterAction | 統一物件導向設計 |
CFilter 基類 | yii\base\ActionFilter | 功能對等 |
accessControl | yii\filters\AccessControl | 功能增強 |