filters()方法定義在CController里,用Gii生成Controller時里面就有filters方法,代碼如下:
public function filters() { // return the filter configuration for this controller, e.g.: return array( 'inlineFilterName', array( 'class'=>'path.to.FilterClass', 'propertyName'=>'propertyValue', ), ); }
這個方法沒有做什么實質性的動作,它只是把你將要執行的過濾方法方法名或者過濾類的類名返回給CController。 我們先看使用方法的方式,也即上面代碼里的’inlineFilterName’含義,這個inlineFilterName意思是在當前控制器的類中有 一個inlineFilterName()方法,該方法里就是你要執行的過濾規則,比如:當前在TestController里:
<?php
class TestController extends CController{
//該方法判斷用戶是否登錄
public function filterInlineFilterName($filterChain){
if (Yii::app()->user->isGuest)
Yii::app()->user->loginRequired();//封裝了登錄的url
$filterChain->run();//參數$filterChain就是執行該filter的action實例,調用$filterChain->run()其實就是執行該action了。
}
public function filters(){
return array('inlineFilterName');
}
}
?>
Ok,上面的代碼就是對當前控制器的所有action都執行了檢查用戶是否登錄了操作,如果用戶未登錄則跳轉到登錄頁,如果登錄則繼續執行action里的內容。這是利用在當前控制器下寫方法的方式執行過濾,同樣,寫成類也是可以的,引入方式
public function filters()
{
// return the filter configuration for this controller, e.g.:
return array(
array(
'class'=>'path.to.FilterClass',//類名
'propertyName'=>'propertyValue',//屬性名,屬性值
),
);
}
那可能有的哥們要問了,那要是我想讓特定的方法檢查是否登錄了怎么做呢?下面就是我要說的了,同樣,還是在TestController里:
<?php
class TestController extends CController{
//該方法判斷用戶是否登錄
public function filterInlineFilterName($filterChain){//必須以filter開頭,后跟名字
if (Yii::app()->user->isGuest && !in_array($filterChain->action->id,$this->inlineFilterNameAction()))
Yii::app()->user->loginRequired();//封裝了登錄的url
$filterChain->run();//參數$filterChain就是執行該filter的action實例,調用$filterChain->run()其實就是執行該action了。
}
public function filters(){
return array('inlineFilterName'),
}
public function inlineFilterNameAction(){//返回要執行過濾的action
return array('action1','action2','action3');
}
}
?>
這樣就可以做到對指定的action添加自定義的過濾規則了。
其實,Yii里已經封裝好了一個過濾類,這里帶大家看看它是怎樣實現的,其實原理和上面一模一樣。我們先來看看CController里的public void filterAccessControl(CFilterChain $filterChain) 方法:
public function filterAccessControl($filterChain)
{
$filter=new CAccessControlFilter;
$filter->setRules($this->accessRules());
$filter->filter($filterChain);
}
可以看到,它是以filter開頭的函數,大家知道它是干嘛的了吧?該方法實例化了一個CAccessControlFilter類,該類就是處理過濾規則的,然后把$this->accessRules()作為一個參數付給 $filter->setRules()方法。 下面來看看accessRules()方法的寫法:
public function accessRules()
{
return array(
'allow', // or 'deny'
//可選規則,本規則適用於列出的所有動作ID(不區分大小寫)
//如果未指定此項,則規則適用於所有動作。
'actions' => array('edit', 'delete'),
//可選規則,本規則適用於列出的所有控制器ID(不區分大小寫)
'controllers' => array('post', 'admin/user'),
//可選規則,本規則適用於列出的所有用戶ID(不區分大小寫)
//使用*號表示所有用戶,?號表示來賓用戶,@表示通過身份驗證的用戶。
'users' => array('thomas', 'kevin'),
//可選規則,本規則適用於列出的所有角色(區分大小寫)。
'roles' => array('admin', 'editor'),
//可選規則,本規則適用於列出的所有IP地址。
//如127.0.0.1, 127.0.0.*
'ips' => array('127.0.0.1'),
//可選規則,本規則適用於列出的所有請求類型(區分大小寫)。
'verbs' => array('GET', 'POST'),
//可選規則,一個PHP表達式,其值表示此規則是否適用
'expression' => '!$user->isGuest && $user->level==2',
//可選規則,顯示自定義的錯誤消息
//自1.1.1版后,此選項開始使用。
'message' => 'Access Denied.',
);
}
好了,這下對Yii的過濾規則大家了解了吧?試着寫寫吧
