YII 过滤器 filters

  1. 云栖社区>
  2. 博客列表>
  3. 正文

YII 过滤器 filters

航空母舰 2016-05-12 16:51:31 浏览998 评论0

摘要: Yii中的过滤器是指,通过配置,在一个控制器的动作被执行之前或者之后执行的一小段代码 。一个例子是,如果我们想要在某个动作执行后额外记录些什么,或者执行一些审核逻辑,可以编写一个简单的审计过滤器来进行这个动作之后的处理任务。

Yii中的过滤器是指,通过配置,在一个控制器的动作被执行之前或者之后执行的一小段代码 。一个例子是,如果我们想要在某个动作执行后额外记录些什么,或者执行一些审核逻辑,可以编写一个简单的审计过滤器来进行这个动作之后的处理任务。

  • beforeValidate 和afterValidate
  • beforeSave 和 afterSave : 这两个将在保存 AR 实例之前和之后被调用。

  • beforeDelete 和 afterDelete : 这两个将在一个 AR 实例被删除之前和之后被调用。

  • afterConstruct : 这个将在每个使用 new 操作符创建 AR 实例后被调用 。

  • beforeFind : 这个将在一个 AR 查找器被用于执行查询(例如 find() , findAll() )之前被调用。

  • afterFind : 这个将在每个 AR 实例作为一个查询结果创建时被调用。

尽量不要用过滤器,过滤器是全局的,可能对其他业务操作造成影响

CWebUser

afterLogin() 用户成功登录后被调用的方法。 CWebUser 
afterLogout() 用户登出后被调用的方法。 CWebUser 
beforeLogin() 在用户登录那一时刻前被调用的方法。 CWebUser 
beforeLogout() 当用户调用logout注销时,将调用该方法。

 

model中

Java代码  收藏代码
  1. protected function  beforeSave() {  
  2.     if($this->isNewRecord){  
  3.         $this->reg_date = $this->modify_date = time();  
  4.         $this->passwd = $this->hasPassword($this->passwd1);  
  5.         $this->credit = 0;  
  6.     }else  
  7.     $this->modify_date = time();  
  8.     if($this->getScenario() == 'changePassword' || $this->getScenario() == 'resetPassword'){  
  9.         $this->passwd = $this->hasPassword($this->passwd1);  
  10.     }  
  11.       
  12.     return parent::beforeSave();  
  13. }  
Java代码  收藏代码
  1. protected function  beforeFind() {  
  2.     parent::beforeFind();  
  3.     $this->getDbCriteria()->addColumnCondition(array('type'=>self::TYPE_WIKI));  
  4.     return true;  
  5. }  
Java代码  收藏代码
  1. protected function afterSave(){  
  2.     parent::afterSave();  
  3.     if(!$this->isNewRecord){  
  4.         $this->dbConnection->createCommand('DELETE FROM PostTag WHERE postId='.$this->id)->execute();  
  5.     }  
  6.     return true;  
  7. }  

一个普遍的例子就是,当我们要求执行某个特定的控制器动作之前,用户必须已经登录,那么可以写一个简单的访问过滤器在这个动作执行之前来检查这个要求。

  • beforeAction
  • afterAction

controller中

Java代码  收藏代码
  1. public function beforeAction($action){  
  2.     if(Yii::app()->user->isGuest&&$action->getId()!='login'){  
  3.         $this->redirect(Yii::app()->loginUrl);  
  4.     }  
  5.     return parent::beforeAction($action);  
  6. }  

Filter过滤器主要是控制访问

YII自定义登录过滤器

Java代码  收藏代码
  1. <?php  
  2.   
  3. class SessionCheckFilter extends CFilter  
  4. {  
  5.     protected function preFilter($filterChain)  
  6.     {  
  7.         if (Yii::app()->user->id > 0) {  
  8.             $filterChain->run();  
  9.         } else {  
  10.             Yii::app()->getController()->redirect(array('user/login'));  
  11.         }  
  12.         return true;  
  13.     }  
  14. }  

 然后在你的Controller中通过filters方法使用,所有XXController继承Controller即可

Java代码  收藏代码
  1. <?php  
  2.   
  3. class Controller extends CController  
  4. {  
  5.   
  6.     public function filters()  
  7.     {  
  8.         return array(  
  9.             array('application.filters.SessionCheckFilter - login, register')  
  10.         );  
  11.     }  
  12. }  

 

Java代码  收藏代码
  1. <?php  
  2.   
  3. class TestController extends CController  
  4. {  
  5.     //该方法判断用户是否登录   
  6.     public function filterInlineFilterName($filterChain)  
  7.     {  
  8.         if (Yii::app()->user->isGuest && !in_array($filterChain->action->id, $this->inlineFilterNameAction())) {  
  9.             Yii::app()->user->loginRequired(); //封装了登录的url  
  10.         }  
  11.   
  12.         $filterChain->run(); //参数$filterChain就是执行该filter的action实例,调用$filterChain->run()其实就是执行该action了。  
  13.     }  
  14.   
  15.     public function filters()  
  16.     {  
  17.         return array('inlineFilterName');  
  18.     }  
  19.   
  20.     public function inlineFilterNameAction()  
  21.     { //返回要执行过滤的action  
  22.         return array('action1''action2''action3');  
  23.     }  
  24. }  

这样就可以做到对指定的action添加自定义的过滤规则了。

其实,Yii里已经封装好了一个过滤类,这里带大家看看它是怎样实现的,其实原理和上面一模一样。我们先来看看CController里的public void filterAccessControl(CFilterChain $filterChain) 方法:

Java代码  收藏代码
  1. public function filterAccessControl($filterChain)  
  2. {  
  3.     $filter=new CAccessControlFilter;  
  4.     $filter->setRules($this->accessRules());  
  5.     $filter->filter($filterChain);  
  6. }  

可以看到,它是以filter开头的函数,大家知道它是干嘛的了吧?该方法实例化了一个CAccessControlFilter 类,该类就是处理过滤规则的,然后把$this->accessRules()作为一个参数付给 $filter->setRules()方法。 下面来看看accessRules()方法的写法:

Java代码  收藏代码
  1. public function accessRules()  
  2. {  
  3.     return array(  
  4.         'allow'// or 'deny'  
  5.         //可选规则,本规则适用于列出的所有动作ID(不区分大小写)  
  6.         //如果未指定此项,则规则适用于所有动作。  
  7.         'actions' => array('edit''delete'),  
  8.         //可选规则,本规则适用于列出的所有控制器ID(不区分大小写)  
  9.         'controllers' => array('post''admin/user'),  
  10.         //可选规则,本规则适用于列出的所有用户ID(不区分大小写)  
  11.         //使用*号表示所有用户,?号表示来宾用户,@表示通过身份验证的用户。  
  12.         'users' => array('thomas''kevin'),  
  13.         //可选规则,本规则适用于列出的所有角色(区分大小写)。  
  14.         'roles' => array('admin''editor'),  
  15.         //可选规则,本规则适用于列出的所有IP地址。  
  16.         //如127.0.0.1, 127.0.0.*  
  17.         'ips' => array('127.0.0.1'),  
  18.         //可选规则,本规则适用于列出的所有请求类型(区分大小写)。  
  19.         'verbs' => array('GET''POST'),  
  20.         //可选规则,一个PHP表达式,其值表示此规则是否适用  
  21.         'expression' => '!$user->isGuest && $user->level==2',  
  22.         //可选规则,显示自定义的错误消息  
  23.         //自1.1.1版后,此选项开始使用。  
  24.         'message' => 'Access Denied.',  
  25.     );  
  26. }  

好了,这下对Yii的过滤规则大家了解了吧?试着写写吧

【云栖快讯】阿里云栖开发者沙龙(Java技术专场)火热来袭!快来报名参与吧!  详情请点击

网友评论

航空母舰
文章540篇 | 关注62
关注
基于云安全大数据能力实现,通过防御SQL注入、XSS跨站脚本、常见Web服务器插件漏洞、木马... 查看详情
为您提供简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效... 查看详情
双12

双12