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的过滤规则大家了解了吧?试着写写吧