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 }
  • 相关阅读:
    多个类定义attr属性重复的问题:Attribute "xxx" has already been defined
    好用的批量改名工具——文件批量改名工具V2.0 绿色版
    得到ImageView中drawable显示的区域的计算方法
    得到view坐标的各种方法
    实现类似于QQ空间相册的点击图片放大,再点后缩小回原来位置
    Material Designer的低版本兼容实现(五)—— ActivityOptionsCompat
    Android 自带图标库 android.R.drawable
    解决 Attempting to destroy the window while drawing!
    解决Using 1.7 requires compiling with Android 4.4 (KitKat); currently using API 4
    Material Designer的低版本兼容实现(四)—— ToolBar
  • 原文地址:https://www.cnblogs.com/dragon16/p/5592046.html
Copyright © 2011-2022 走看看