xp796

xp796

这家伙有点懒,还没写个性签名!

  • 财富值1115
  • 威望值10
  • 总积分1465

个人信息

  • 赞了话题
    Yii2依赖注入容器讲解
  • 赞了源码
    Yii2 后台脚本管理系统
  • 2016-09-02 已签到
    连续签到2天,获得了10个金钱
  • 2016-09-01 已签到
    连续签到1天,获得了5个金钱
  • 2016-08-26 已签到
    连续签到4天,获得了20个金钱
  • 赞了回答

    你给的例子,其实不能完全说明 behaviors 的行为,这里是 filter 的行为,但 filteryii2yii 中的实现不一样,yii2 中的 filter 是特殊的 behavior ,被框架多加了一层的处理,这里我只说明下 filter 的调用, 普通的 behavior 我暂时还没有用到,不清楚

    一句话,QueryParamAuthauthenticator() 方法,是在 Controller 调用 beforeAction 时触发的,你可以在 Controller 复写 beforeAction 方法为空操作,看看还会不会调用。

    在底层的 Controller 中,beforeAction 执行了 $this->trigger(self::EVENT_BEFORE_ACTION, $event) 触发了 EVENT_BEFORE_ACTION 事件,在 yii\base\Componenttrigger 会首先 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 的,来看看 ActionFilterattach 时会做什么

    /**
     * @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,如 exceptonly 检测,这个 beforeAction 正是你写 filter 时需要复写的一个方法,至于 QueryParamAuthauthenticator() 方法,自己可以接着走代码

    入口是 ControllerbeforeAction 方法,可以自己走一遍源代码,就这些

  • 2016-08-25 已签到
    连续签到3天,获得了15个金钱
  • 2016-08-24 已签到
    连续签到2天,获得了10个金钱
经理 等级规则
1465/2000
资料完整度
10/100
用户活跃度
0/100

Ta的关注

15

Ta的粉丝

3

Ta的访客

7