Yii中利用filters/accesRules來控制訪問

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的過濾規則大家瞭解了吧?試着寫寫吧

發佈了18 篇原創文章 · 獲贊 2 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章