xp796
- xp796 赞了话题Yii2依赖注入容器讲解
- xp796 赞了源码Yii2 后台脚本管理系统
- xp796 2016-09-02 已签到连续签到2天,获得了10个金钱
- xp796 2016-09-01 已签到连续签到1天,获得了5个金钱
- xp796 2016-08-26 已签到连续签到4天,获得了20个金钱
- xp796 赞了回答
你给的例子,其实不能完全说明
behaviors
的行为,这里是filter
的行为,但filter
在yii2
和yii
中的实现不一样,yii2
中的filter
是特殊的behavior
,被框架多加了一层的处理,这里我只说明下filter
的调用, 普通的behavior
我暂时还没有用到,不清楚一句话,
QueryParamAuth
中authenticator()
方法,是在Controller
调用beforeAction
时触发的,你可以在Controller
复写beforeAction
方法为空操作,看看还会不会调用。在底层的
Controller
中,beforeAction
执行了$this->trigger(self::EVENT_BEFORE_ACTION, $event)
触发了EVENT_BEFORE_ACTION
事件,在yii\base\Component
中trigger
会首先ensureBehaviors()
,把behaviors()
定义的行为附加到Controller
上/** * Makes sure that the behaviors declared in [[behaviors()]] are attached to this component. */ public function ensureBehaviors() { if ($this->_behaviors === null) { $this->_behaviors = []; foreach ($this->behaviors() as $name => $behavior) { $this->attachBehaviorInternal($name, $behavior); } } } /** * Attaches a behavior to this component. * @param string|integer $name the name of the behavior. If this is an integer, it means the behavior * is an anonymous one. Otherwise, the behavior is a named one and any existing behavior with the same name * will be detached first. * @param string|array|Behavior $behavior the behavior to be attached * @return Behavior the attached behavior. */ private function attachBehaviorInternal($name, $behavior) { if (!($behavior instanceof Behavior)) { $behavior = Yii::createObject($behavior); } if (is_int($name)) { $behavior->attach($this); $this->_behaviors[] = $behavior; } else { if (isset($this->_behaviors[$name])) { $this->_behaviors[$name]->detach(); } $behavior->attach($this); $this->_behaviors[$name] = $behavior; } return $behavior; }
}
QueryParamAuth
最终继承自ActionFilter
的,来看看ActionFilter
在attach
时会做什么/** * @inheritdoc */ public function attach($owner) { $this->owner = $owner; $owner->on(Controller::EVENT_BEFORE_ACTION, [$this, 'beforeFilter']); }
会在
Controller
上绑定一个EVENT_BEFORE_ACTION
事件,行为是执行自己的beforeFilter
方法/** * @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; } }
到这里,你看到了,
ActionFilter
最终会执行自己的beforeAction
方法,当然这可不是Controller
中的beforeAction
方法,还会处理些前置check,如except
和only
检测,这个beforeAction
正是你写 filter 时需要复写的一个方法,至于QueryParamAuth
的authenticator()
方法,自己可以接着走代码入口是
Controller
的beforeAction
方法,可以自己走一遍源代码,就这些 - xp796 2016-08-25 已签到连续签到3天,获得了15个金钱
- xp796 2016-08-24 已签到连续签到2天,获得了10个金钱