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裏:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?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裏的內容。這是利用在當前控制器下寫方法的方式執行過濾,同樣,寫成類也是可以的,引入方式
1
2
3
4
5
6
7
8
9
10
|
public function filters() { //
return the filter configuration for this controller, e.g.: return array ( array ( 'class' => 'path.to.FilterClass' , //類名 'propertyName' => 'propertyValue' , //屬性名,屬性值 ), ); } |
那可能有的哥們要問了,那要是我想讓特定的方法檢查是否登錄了怎麼做呢?下面就是我要說的了,同樣,還是在TestController裏:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<?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) 方法:
1
2
3
4
5
6
|
public function filterAccessControl( $filterChain ) { $filter = new CAccessControlFilter; $filter ->setRules( $this ->accessRules()); $filter ->filter( $filterChain ); } |
可以看到,它是以filter開頭的函數,大家知道它是幹嘛的了吧?該方法實例化了一個CAccessControlFilter類,該類就是處理過濾規則的,然後把$this->accessRules()作爲一個參數付給 $filter->setRules()方法。 下面來看看accessRules()方法的寫法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
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的過濾規則大家瞭解了吧?試着寫寫吧