Yii2.0的ActionFilter类详细解读
来源:互联网 发布:风暴英雄数据查询 编辑:程序博客网 时间:2024/06/03 17:29
1.涉及的属性和方法:
yii\base\ActionFilter中public function attach(){ 把beforeFileter绑定到Controller的EVENT_BEFORE_ACTION事件上}public function detach(){ 1.将beforeFileter从Controller的EVENT_BEFORE_ACTION事件上解绑 2.将afterFilter从Controller的EVENT_AFTER_ACTION事件上解绑}public function beforeFilter(){ 调用self的beforeAction方法, 返回真则把afterFilter绑定到Controller的EVENT_AFTER_ACTION事件上 返回假。。。。?}public function afterFilter(){ 调用self的afterAction方法 将afterFilter从Controller的EVENT_AFTER_ACTION事件上解绑}public function beforeAction(){ 在子类中可以重写并自定义处理,默认返回true}public function afterAction(){ 在子类中可以重写并自定义处理,默认返回true}
2.使用方式
我们的研究对象是ActionFilter和Controller,这一点要特别注意ActionFilter在controller的behaviors()方法中添加
例如:
public function behaviors(){ $behaviors = parent::behaviors(); $behaviors[ 'access' => [ 'class' => AccessComponent::className()//没有use的话需要写类的全名,即包括命名空间的类名,AccessComponent是ActionFilter的子类 ] ]; return $behaviors;}
3.运行机制解析
A.首先我们需要了解一些yii2.0中关于行为的知识,需要深入了解的请移步:http://www.digpage.com/behavior.html
1).yii/base/Component中加入了对行为(behaviors)的支持
Component的ensureBehaviors()方法会获取behaviors()方法返回的数组【注1】,
将数组中配置的行为类通过Yii::createObject创建出对象【注2】,
并调用行为的attach方法(一般是注册一个事件)【注3】,
然后将行为对象放到_behaviors数组中【注4】
下面两段代码是yii/base/Component的源码public function ensureBehaviors(){ if ($this->_behaviors === null) { $this->_behaviors = []; foreach ($this->behaviors() as $name =>$behavior) { //【注1】 $this->attachBehaviorInternal($name, $behavior); } }}private function attachBehaviorInternal($name, $behavior){ if (!($behavior instanceof Behavior)) { $behavior = Yii::createObject($behavior);//创建行为对象【注2】 } if (is_int($name)) {//通过判断是否是索引来判断是否是匿名行为 $behavior->attach($this);//绑定事件【注3】 $this->_behaviors[] = $behavior;【注4】 } else { if (isset($this->_behaviors[$name])) {//如果该行为已存在,则注销此行为 $this->_behaviors[$name]->detach(); } $behavior->attach($this);【注3】 $this->_behaviors[$name] = $behavior;【注4】 } return $behavior;}
2).
在component的__set,__get,__isset,__unset,__call,on,off,trigger,attachBehavior等方法中,都在调用了ensureBehaviors()方法。也就是说在你调用component对象中不存在的属性和方法,设置不存在的属性和方法,绑定事件,解绑事件,触发事件,绑定行为时,都会首先把behaviors()方法中声明的行为注册(即new 出对象,调用attach方法绑定事件,将行为对象储存到_behaviors属性中)。这么处理是Yii2.0懒加载,即需要用到的时候才会new
3).
还有一个事实是,yii2.0中的组件基本都继承自Component类,其中我们用到的Controller正是继承自Component
B.关于事件的知识
对于Yii2.0的事件,同一个事件可以绑定多个handler(即处理方法),当trigger这个事件的时候,handler会按绑定顺序执行。想要了解更多关于事件的知识,请移步:http://www.digpage.com/event.html
C.关于请求进入Yii2.0的生命周期(重点看如何进入特定Controller的Action)
1).入口脚本index.php
new yii\web\Application($config))->run();
2).run()方法,继承自yii\base\Application
其中有这么一段代码
$response = $this->handleRequest($this->getRequest());
3).handleRequest()方法,在子类yii\web\Application中重写
看这段代码
$result = $this->runAction($route, $params);
4).runAction方法,在yii\base\Module中
这里我们看到,它先new了Controller对象,然后调用controller的runAction方法来执行相应的Action
result = $controller->runAction($actionID, $params);
5).controller的runAction()方法,在yii\base\Controller中
$this->beforeAction($action)
6).beforeAction
$this->trigger(self::EVENT_BEFORE_ACTION, $event);yii\base\Component中public function trigger($name, Event $event = null){ $this->ensureBehaviors();//注册行为 if (!empty($this->_events[$name])) {//调用事件handler if ($event === null) { $event = new Event; } if ($event->sender === null) { $event->sender = $this; } $event->handled = false; $event->name = $name; foreach ($this->_events[$name] as $handler) { $event->data = $handler[1]; call_user_func($handler[0], $event); // stop further handling if the event is handled if ($event->handled) { return; } } } // invoke class-level attached handlers Event::trigger($this, $name, $event);}
D.有了以上知识,我们大体可以梳理下ActionFilter的实现机制了
在C的6)之后,$this->trigger会先调用我们在A中提到ensureBehaviors()方法:
1)注册行为(并调用attach()方法,ActionFilter的attach方法是给Controller的before action事件绑定这个类的beforeFilter方法),
2)然后顺序调用对应事件_events数组中的handler(根据A的分析,我们可以判断出:多个ActionFilter的beforeFilter方法是顺序绑定到controller的before action事件中的)
4.总结
一个大体的思路就是
1)request进入index.php
2)new application并执行run
3)new Controller并执行runAction
4)runAction先执行beforeAction
5)beforeAction调用trigger方法,触发before action
6)trigger方法先注册行为,
对于ActionFilter行为来说,在注册过程中会按行为定义的顺序给controller的before action事件添加handler,其中每个handler就是对应的ActionFilter的beforeFilter方法,因为beforeFilter方法会调用它自己的beforeAction方法,可以认为handler就是每一个ActionFilter的beforeAction方法。
7)注册完后,顺序执行before action的handler
自此ActionFilter的功能告一段落,至于afterFilter,读者可以自行梳理,原理差不多是一致的
个人博客链接http://www.tanklh.cc/typecho/index.php/archives/4/
- Yii2.0的ActionFilter类详细解读
- ActionFilter类
- ActionFilter的执行机制
- 基于rbac的ActionFilter
- Yii2.0详细讲解
- yii2框架的详细介绍
- yii2框架的详细介绍
- yii2框架的详细介绍
- 详细解读LruCache类
- 详细解读LruCache类
- 详细解读LruCache类
- 详细解读LruCache类
- 详细解读LruCache类
- 详细解读LruCache类
- yii2-gii的详细操作步骤
- yii2 RESTful api的详细使用
- yii2 RESTful api的详细使用
- yii2.0-captcha验证码--详细设置
- JAVA之ArrayList
- 回顾大一·C语言编程3.4(2)
- POJ 2996.Help Me with the Game
- jsp动态嵌入另一个jsp页面
- Android将网页做成app-- Jsoup网络解析框架
- Yii2.0的ActionFilter类详细解读
- OPENSTACK NETWORKING 概念
- BOM(浏览器对象模型)和DOM(文档对象模型)
- [js高手之路] html5 canvas系列教程
- 关于Python+Opencv实现人脸检测的实验笔记(调用摄像头篇)
- Python扩展方法一二事
- OpenGL从1.0开始-顶点数组简析
- JavaScript 面向对象编程
- Lintcode删除链表中的元素