zoukankan      html  css  js  c++  java
  • yii2源码学习笔记(十六)

    Module类的最后代码

      1     /**
      2      * Registers sub-modules in the current module.
      3      * 注册子模块到当前模块
      4      * Each sub-module should be specified as a name-value pair, where
      5      * name refers to the ID of the module and value the module or a configuration
      6      * array that can be used to create the module. In the latter case, [[Yii::createObject()]]
      7      * will be used to create the module.
      8      * 子模块以键值对的方式指定,键名为模块ID,键值为模块对象或者用于创建模块对象的配置数组
      9      * If a new sub-module has the same ID as an existing one, the existing one will be overwritten silently.
     10      * 如果标识相同 会覆盖
     11      * The following is an example for registering two sub-modules:
     12      *
     13      * ~~~
     14      * [
     15      *     'comment' => [
     16      *         'class' => 'appmodulescommentCommentModule',
     17      *         'db' => 'db',
     18      *     ],
     19      *     'booking' => ['class' => 'appmodulesookingBookingModule'],
     20      * ]
     21      * ~~~
     22      *
     23      * @param array $modules modules (id => module configuration or instances)
     24      */
     25     public function setModules($modules)
     26     {
     27         foreach ($modules as $id => $module) {
     28             $this->_modules[$id] = $module; //注册子模块,覆盖同名模块
     29         }
     30     }
     31 
     32     /**
     33      * Runs a controller action specified by a route.   运行路由中指定的控制器方法
     34      * This method parses the specified route and creates the corresponding child module(s), controller and action
     35      * instances. It then calls [[Controller::runAction()]] to run the action with the given parameters.
     36      * If the route is empty, the method will use [[defaultRoute]].
     37      * 解析指定的路由,创建对应的子模块、控制器、方法实例,调用[[Controller::runAction()]]给定的参数运行控制器中的方法
     38      * @param string $route the route that specifies the action.    指定行动的路线。
     39      * @param array $params the parameters to be passed to the action 操作的参数
     40      * @return mixed the result of the action.  操作结果
     41      * @throws InvalidRouteException if the requested route cannot be resolved into an action successfully
     42      */
     43     public function runAction($route, $params = [])
     44     {
     45         $parts = $this->createController($route); //根据路由创建控制器
     46         if (is_array($parts)) {
     47             /* @var $controller Controller */
     48             list($controller, $actionID) = $parts; //获得$actionId和$controller
     49             $oldController = Yii::$app->controller;
     50             Yii::$app->controller = $controller;
     51             $result = $controller->runAction($actionID, $params); //运行控制器 加载action方法
     52             Yii::$app->controller = $oldController;
     53 
     54             return $result;
     55         } else {
     56             $id = $this->getUniqueId();
     57             throw new InvalidRouteException('Unable to resolve the request "' . ($id === '' ? $route : $id . '/' . $route) . '".');
     58         }
     59     }
     60 
     61     /**
     62      * Creates a controller instance based on the given route.
     63      * 根据给定的路径创建一个控制器实例。
     64      * The route should be relative to this module. The method implements the following algorithm
     65      * to resolve the given route:
     66      * 相对这个模块的路径。该方法实现了以下算法来解决给定的路径:
     67      * 1. If the route is empty, use [[defaultRoute]];   路径为空,调用默认的路径
     68      * 2. If the first segment of the route is a valid module ID as declared in [[modules]],
     69      *    call the module's `createController()` with the rest part of the route;
     70      * 3. If the first segment of the route is found in [[controllerMap]], create a controller
     71      *    based on the corresponding configuration found in [[controllerMap]];
     72      * 4. The given route is in the format of `abc/def/xyz`. Try either `abcDefController`
     73      *    or `abcdefXyzController` class within the [[controllerNamespace|controller namespace]].
     74      *
     75      * If any of the above steps resolves into a controller, it is returned together with the rest
     76      * part of the route which will be treated as the action ID. Otherwise, false will be returned.
     77      *
     78      * @param string $route the route consisting of module, controller and action IDs.
     79      * 由模块、控制器和动作标识组成的路径。
     80      * @return array|boolean If the controller is created successfully, it will be returned together
     81      * with the requested action ID. Otherwise false will be returned.
     82      * 如果控制器成功创建,将与被请求的操作标识一起返回,否则将返回false。
     83      * @throws InvalidConfigException if the controller class and its file do not match.
     84      * 如果控制器类及其文件不匹配,抛出异常
     85      */
     86     public function createController($route)
     87     {
     88         if ($route === '') {//路径为空,调用默认的路径
     89             $route = $this->defaultRoute;
     90         }
     91 
     92         // double slashes or leading/ending slashes may cause substr problem
     93         $route = trim($route, '/'); //去掉两边的反斜线,
     94         if (strpos($route, '//') !== false) {
     95             return false; //如果路径中包含双斜线,返回false
     96         }
     97 
     98         if (strpos($route, '/') !== false) {
     99             list ($id, $route) = explode('/', $route, 2);//将路径按反斜线分割为两个元素的数组,
    100         } else {
    101             $id = $route;
    102             $route = '';
    103         }
    104 
    105         // module and controller map take precedence  优先判断模块和控制器映射
    106         if (isset($this->controllerMap[$id])) {
    107             //如果$id是控制器ID,实例化控制器,返回控制器实例和后面的路径$route
    108             $controller = Yii::createObject($this->controllerMap[$id], [$id, $this]);
    109             return [$controller, $route];
    110         }
    111         $module = $this->getModule($id);
    112         if ($module !== null) {//如果$id是模块ID,实例化控制器,返回控制器实例和后面的路径$route
    113             return $module->createController($route);
    114         }
    115 
    116         if (($pos = strrpos($route, '/')) !== false) {
    117             //上面两种情况都不是,则表示还有子模块,构造子模块的标识
    118             $id .= '/' . substr($route, 0, $pos);
    119             $route = substr($route, $pos + 1);
    120         }
    121 
    122         $controller = $this->createControllerByID($id);
    123         if ($controller === null && $route !== '') {//实例化控制器 组装控制器实例和后面的路径$route
    124             $controller = $this->createControllerByID($id . '/' . $route);
    125             $route = '';
    126         }
    127         //存在返回控制器实例和后面的路径$route,否则返回false
    128         return $controller === null ? false : [$controller, $route];
    129     }
    130 
    131     /**
    132      * Creates a controller based on the given controller ID.
    133      * 根据给定的控制器标识创建控制器
    134      * The controller ID is relative to this module. The controller class
    135      * should be namespaced under [[controllerNamespace]].
    136      * 当前模块的控制器标识,控制器类应在 [[controllerNamespace]]的命名空间下
    137      * Note that this method does not check [[modules]] or [[controllerMap]].
    138      *
    139      * @param string $id the controller ID  控制器标识
    140      * @return Controller the newly created controller instance, or null if the controller ID is invalid.
    141      *  新创建的控制器实例,为null则控制器标识无效
    142      * @throws InvalidConfigException if the controller class and its file name do not match.
    143      * This exception is only thrown when in debug mode.
    144      */
    145     public function createControllerByID($id)
    146     {
    147         $pos = strrpos($id, '/');
    148         if ($pos === false) {
    149             $prefix = ''; //是否包含反斜线,
    150             $className = $id;
    151         } else {//将路径按反斜线分割为两个元素
    152             $prefix = substr($id, 0, $pos + 1);
    153             $className = substr($id, $pos + 1);
    154         }
    155 
    156         if (!preg_match('%^[a-z][a-z0-9\-_]*$%', $className)) {
    157             return null;//正则判断是否符合规则
    158         }
    159         if ($prefix !== '' && !preg_match('%^[a-z0-9_/]+$%i', $prefix)) {
    160             return null;
    161         }
    162         //组装控制器名
    163         $className = str_replace(' ', '', ucwords(str_replace('-', ' ', $className))) . 'Controller';
    164         $className = ltrim($this->controllerNamespace . '\' . str_replace('/', '\', $prefix)  . $className, '\');
    165         if (strpos($className, '-') !== false || !class_exists($className)) {
    166             return null; //控制器名有 ‘-’或不存在则为null
    167         }
    168 
    169         if (is_subclass_of($className, 'yiiaseController')) {//检查对象是否有父类或子类
    170             return Yii::createObject($className, [$id, $this]); //创建控制器
    171         } elseif (YII_DEBUG) {
    172             throw new InvalidConfigException("Controller class must extend from \yii\base\Controller.");
    173         } else {
    174             return null;
    175         }
    176     }
    177 
    178     /**
    179      * This method is invoked right before an action within this module is executed.
    180      * 当前模块的Action执行前调用的方法,将触发[[EVENT_BEFORE_ACTION]]事件
    181      * The method will trigger the [[EVENT_BEFORE_ACTION]] event. The return value of the method
    182      * will determine whether the action should continue to run.
    183      * 如果返回true,Action方法才会执行
    184      * If you override this method, your code should look like the following:
    185      *
    186      * ```php
    187      * public function beforeAction($action)
    188      * {
    189      *     if (parent::beforeAction($action)) {
    190      *         // your custom code here
    191      *         return true;  // or false if needed
    192      *     } else {
    193      *         return false;
    194      *     }
    195      * }
    196      * ```
    197      *
    198      * @param Action $action the action to be executed. 要执行的操作
    199      * @return boolean whether the action should continue to be executed.   是否执行操作
    200      */
    201     public function beforeAction($action)
    202     {
    203         $event = new ActionEvent($action);
    204         $this->trigger(self::EVENT_BEFORE_ACTION, $event);//触发beforeAction事件
    205         return $event->isValid;
    206     }
    207 
    208     /**
    209      * This method is invoked right after an action within this module is executed.
    210      * 当前模块的Action执行后调用的方法,触发[[EVENT_AFTER_ACTION]]事件
    211      * The method will trigger the [[EVENT_AFTER_ACTION]] event. The return value of the method
    212      * will be used as the action return value.
    213      * 如果返回true,后面的代码才会继续执行
    214      * If you override this method, your code should look like the following:
    215      *
    216      * ```php
    217      * public function afterAction($action, $result)
    218      * {
    219      *     $result = parent::afterAction($action, $result);
    220      *     // your custom code here
    221      *     return $result;
    222      * }
    223      * ```
    224      *
    225      * @param Action $action the action just executed.  执行的操作
    226      * @param mixed $result the action return result.   执行结果
    227      * @return mixed the processed action result.   处理结果
    228      */
    229     public function afterAction($action, $result)
    230     {
    231         $event = new ActionEvent($action);
    232         $event->result = $result;
    233         $this->trigger(self::EVENT_AFTER_ACTION, $event);//触发beforeAction事件
    234         return $event->result;
    235     }
    236 }
  • 相关阅读:
    小程序样式表不支持级联选择器
    小程序为什么脚本内不能使用window等对象
    微信小程序怎么获取用户输入
    php中不借助IDE快速定位行数或者方法定义的文件和位置
    百度Ueditor编辑器取消多图上传对话框中的图片搜索
    阿里云ECS购买优惠码
    DEDE 5.7中各函数所在的文件和位置
    自定义的parse_url逆向函数http_build_url,将数组转为url字符串
    PHPMailer fe v4.11 For Thinkphp 3.2
    javascript使用技巧总结,不断更新...
  • 原文地址:https://www.cnblogs.com/dragon16/p/5592046.html
Copyright © 2011-2022 走看看