学习yii2.0框架阅读代码(二十一)

vendor/yiisoft/yii2/base/Module.php(完)

   /**
     * 创建一个控制器基于给定控制器ID.
     *
     * The controller ID is relative to this module. The controller class
     * should be namespaced under [[controllerNamespace]].
     *
     * Note that this method does not check [[modules]] or [[controllerMap]].
     *
     * @param string $id the controller ID
     * @return Controller the newly created controller instance, or null if the controller ID is invalid.
     * @throws InvalidConfigException if the controller class and its file name do not match.
     * This exception is only thrown when in debug mode.
     */
    public function createControllerByID($id)
    {
        // $id是controller的ID,但它前面可能带有module的ID,而且可能是多层module ID
        // 取到最右边的斜线位置,可以分离出controller的名字
        $pos = strrpos($id, '/');
        if ($pos === false) {
            // 没有斜线,$id就是controller的名字
            $prefix = '';
            $className = $id;
        } else {
            // 有斜线,斜线前的是module的ID,斜线后是controller的名字
            $prefix = substr($id, 0, $pos + 1);
            $className = substr($id, $pos + 1);
        }

        if (!preg_match('%^[a-z][a-z0-9\-_]*$%', $className)) {
            // 如果controller的名字不符合命名的规范,就返回null
            // 以小写字母开头,可以包含数字/小写字母/右斜线/中划线/下划线
            return null;
        }
        if ($prefix !== '' && !preg_match('%^[a-z0-9_/]+$%i', $prefix)) {
            // 如果module的ID不符合module的命名规范,就返回null
            // 可以包含数字/小写字母/左斜线/下划线
            return null;
        }

        // 先将-替换为空格,再将每个单词的首字母大写,再将空格替换为空字符串,最后拼接上'Controller',就拿到了类名(不带namespace)
        $className = str_replace(' ', '', ucwords(str_replace('-', ' ', $className))) . 'Controller';
        // 根据application和module中定义的controllerNamespace,拼出controller的类名,含namespace
        $className = ltrim($this->controllerNamespace . '\' . str_replace('/', '\', $prefix)  . $className, '\');
        if (strpos($className, '-') !== false || !class_exists($className)) {
            // 如果存在中划线或者类不存在,即返回null
            return null;
        }

        // is_subclass_of — 如果此对象是该类的子类,则返回 TRUE
        // 判断是不是'yiiaseController'的子类,是的话,就创建相应类的实例
        if (is_subclass_of($className, 'yiiaseController')) {
            return Yii::createObject($className, [$id, $this]);
        } elseif (YII_DEBUG) {
            throw new InvalidConfigException("Controller class must extend from \yii\base\Controller.");
        } else {
            return null;
        }
    }

    /**
     * This method is invoked right before an action within this module is executed.
     * 这个方法被调用之前执行一个动作在这个模块
     * The method will trigger the [[EVENT_BEFORE_ACTION]] event. The return value of the method
     * will determine whether the action should continue to run.
     *
     * If you override this method, your code should look like the following:
     *
     * ```php
     * public function beforeAction($action)
     * {
     *     if (parent::beforeAction($action)) {
     *         // your custom code here
     *         return true;  // or false if needed
     *     } else {
     *         return false;
     *     }
     * }
     * ```
     *
     * @param Action $action the action to be executed.
     * @return boolean whether the action should continue to be executed.
     */
    public function beforeAction($action)
    {
        $event = new ActionEvent($action);
        //该方法将触发[[EVENT_BEFORE_ACTION]]事件
        $this->trigger(self::EVENT_BEFORE_ACTION, $event);
        return $event->isValid;
    }

    /**
     * This method is invoked right after an action within this module is executed.
     *调用该方法之后执行一个动作在这个模块。
     * The method will trigger the [[EVENT_AFTER_ACTION]] event. The return value of the method
     * will be used as the action return value.
     *
     * If you override this method, your code should look like the following:
     *
     * ```php
     * public function afterAction($action, $result)
     * {
     *     $result = parent::afterAction($action, $result);
     *     // your custom code here
     *     return $result;
     * }
     * ```
     *
     * @param Action $action the action just executed.
     * @param mixed $result the action return result.
     * @return mixed the processed action result.
     */
    public function afterAction($action, $result)
    {   //初始化
        $event = new ActionEvent($action);
        //该事件触发后赋值给$result
        $event->result = $result;
        //该方法将触发[[EVENT_BEFORE_ACTION]]事件
        $this->trigger(self::EVENT_AFTER_ACTION, $event);
        return $event->result;
    }
}
原文地址:https://www.cnblogs.com/xwzj/p/5453667.html