yii2 controller behavior函数的beforeAction实现原理
来源:互联网 发布:手机网络加速器破解版 编辑:程序博客网 时间:2024/05/16 04:56
首先写一个例子,在siteController中覆盖behaviors函数
public function behaviors() { return [ 'access' => [ 'class'=>AuthFilter::className(), 'only'=>['index'], ], 'access11' => [ 'class'=>AuthFilter::className(), 'only'=>['index'], ], ]; }
AuthFilter的定义
class AuthFilter extends ActionFilter{ public function beforeAction($action) { echo 'this is echo when before Action'; return parent::beforeAction($action); // TODO: Change the autogenerated stub } public function afterAction($action, $result) { echo 'this is echo when after action'; return parent::afterAction($action, $result); // TODO: Change the autogenerated stub }}
我们知道controller的拦截器是在behavior中进行定义的,而controller的拦截器的函数必须定义beforeAction 和afterAction,这是为什么呢,因为这是当前Controller的祖父类定义的!!!
我的SiteController的父类是web的Controller,该类的父类是yii\base\controller,每次 一个请求的到来,都会执行祖父类Controller的runAction
public function runAction($id, $params = []) { $action = $this->createAction($id); if ($action === null) { throw new InvalidRouteException('Unable to resolve the request: ' . $this->getUniqueId() . '/' . $id); } Yii::trace('Route to run: ' . $action->getUniqueId(), __METHOD__); if (Yii::$app->requestedAction === null) { Yii::$app->requestedAction = $action; } $oldAction = $this->action; $this->action = $action; $modules = []; $runAction = true; // call beforeAction on modules foreach ($this->getModules() as $module) { if ($module->beforeAction($action)) { //这里执行了一次,调用点是yii\web\application array_unshift($modules, $module); } else { $runAction = false; break; } } $result = null; if ($runAction && $this->beforeAction($action)) { //可以看到,执行beforeAction之后,并且返回true,之后参会进行下一步操作 // run the action $result = $action->runWithParams($params); $result = $this->afterAction($action, $result); // call afterAction on modules foreach ($modules as $module) { /* @var $module Module */ $result = $module->afterAction($action, $result); } } $this->action = $oldAction; return $result; }
祖父类执行了beforeAction,但是大家需要注意的是beforeAction执行了两次,一次是web\application执行beforeAction,这样是不会执行我们controller中的behavior中的beforeAction函数的,而当执行$this->beforeAction的时候其定义如下:
public function beforeAction($action) { $event = new ActionEvent($action); $this->trigger(self::EVENT_BEFORE_ACTION, $event); return $event->isValid; }这样就触发了trigger函数,其函数定义如下:
public function trigger($name, Event $event = null) { $this->ensureBehaviors(); if (!empty($this->_events[$name])) { 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);//此处进行beforeAction的调用 // stop further handling if the event is handled if ($event->handled) { return; } } } // invoke class-level attached handlers Event::trigger($this, $name, $event); }因为我们在$this 也就是siteController中定义了behaviors函数,在ensureBahaviors中就将behavior放在了component中的_behaviors数组当中,同时将对应的数据写在了_events当中,其$name 也是beforeAction,这样就会执行call_user_func函数,调用我们的接口
只是此时$name 是beforeAction,而 $handler是一个数组,第一个元素是定义类的对象,第二个是要执行的函数名称"beforeFilter",该函数的定义是在ActionFilter类中定义的
/** * @param ActionEvent $event */ public function beforeFilter($event) { if (!$this->isActive($event->action)) { return; } $event->isValid = $this->beforeAction($event->action); if ($event->isValid) { // call afterFilter only if beforeFilter succeeds // beforeFilter and afterFilter should be properly nested $this->owner->on(Controller::EVENT_AFTER_ACTION, [$this, 'afterFilter'], null, false); } else { $event->handled = true; } }
由该函数转调子类的beforeAction,这样就完成了我们的整个操作,需要注意的是如果有多个behavior的时候,则会根据behaviors数组的顺序,依次进行调用!!!
0 0
- yii2 controller behavior函数的beforeAction实现原理
- yii2 module类的behavior函数
- yii2 在控制器重写 beforeAction() 方法时,behaviors 失效的原因
- yii2中beforeAction中redirect()不起作用
- yii2.0 beforeAction 防非法登陆
- Yii2 property,behavior,event
- YII2 学习笔记 --- Behavior
- yii2 - controller
- Yii2学习笔记(九):行为Behavior的使用
- yii2 session 的原理
- yii2的rules()函数
- 了解.net MVC的实现原理Controller/Action
- 了解.net MVC的实现原理Controller/Action
- Yii2—控制器(Controller)
- Yii2 理解Controller
- Yii2—控制器(Controller)
- yii2实现队列及队列原理
- Yii2 Layout 传值实现和原理
- ORACLE 导出错误 EXP-00008: 遇到 Oracle 错误 904
- 华为OJ——数字颠倒
- VC++中Format函数详解
- Educational Codeforces Round 15 B. Powers of Two (数学)
- Java compiler level does not match the version of the installed Java project facet.
- yii2 controller behavior函数的beforeAction实现原理
- 190 git post-receive 钩子不能正常执行 git pull
- 红黑树元素的插入和删除
- C++错题
- (1)Linux下Hadoop2.6集群的搭建
- c语言编写访问者模式
- Java 从服务器下载文件到本地
- 新浪 java试题
- Google Protocol Buffer项目无法加载解决方案