Module类的最后代码

     /**
* Registers sub-modules in the current module.
* 注册子模块到当前模块
* Each sub-module should be specified as a name-value pair, where
* name refers to the ID of the module and value the module or a configuration
* array that can be used to create the module. In the latter case, [[Yii::createObject()]]
* will be used to create the module.
* 子模块以键值对的方式指定,键名为模块ID,键值为模块对象或者用于创建模块对象的配置数组
* If a new sub-module has the same ID as an existing one, the existing one will be overwritten silently.
* 如果标识相同 会覆盖
* The following is an example for registering two sub-modules:
*
* ~~~
* [
* 'comment' => [
* 'class' => 'app\modules\comment\CommentModule',
* 'db' => 'db',
* ],
* 'booking' => ['class' => 'app\modules\booking\BookingModule'],
* ]
* ~~~
*
* @param array $modules modules (id => module configuration or instances)
*/
public function setModules($modules)
{
foreach ($modules as $id => $module) {
$this->_modules[$id] = $module; //注册子模块,覆盖同名模块
}
} /**
* Runs a controller action specified by a route. 运行路由中指定的控制器方法
* This method parses the specified route and creates the corresponding child module(s), controller and action
* instances. It then calls [[Controller::runAction()]] to run the action with the given parameters.
* If the route is empty, the method will use [[defaultRoute]].
* 解析指定的路由,创建对应的子模块、控制器、方法实例,调用[[Controller::runAction()]]给定的参数运行控制器中的方法
* @param string $route the route that specifies the action. 指定行动的路线。
* @param array $params the parameters to be passed to the action 操作的参数
* @return mixed the result of the action. 操作结果
* @throws InvalidRouteException if the requested route cannot be resolved into an action successfully
*/
public function runAction($route, $params = [])
{
$parts = $this->createController($route); //根据路由创建控制器
if (is_array($parts)) {
/* @var $controller Controller */
list($controller, $actionID) = $parts; //获得$actionId和$controller
$oldController = Yii::$app->controller;
Yii::$app->controller = $controller;
$result = $controller->runAction($actionID, $params); //运行控制器 加载action方法
Yii::$app->controller = $oldController; return $result;
} else {
$id = $this->getUniqueId();
throw new InvalidRouteException('Unable to resolve the request "' . ($id === '' ? $route : $id . '/' . $route) . '".');
}
} /**
* Creates a controller instance based on the given route.
* 根据给定的路径创建一个控制器实例。
* The route should be relative to this module. The method implements the following algorithm
* to resolve the given route:
* 相对这个模块的路径。该方法实现了以下算法来解决给定的路径:
* 1. If the route is empty, use [[defaultRoute]]; 路径为空,调用默认的路径
* 2. If the first segment of the route is a valid module ID as declared in [[modules]],
* call the module's `createController()` with the rest part of the route;
* 3. If the first segment of the route is found in [[controllerMap]], create a controller
* based on the corresponding configuration found in [[controllerMap]];
* 4. The given route is in the format of `abc/def/xyz`. Try either `abc\DefController`
* or `abc\def\XyzController` class within the [[controllerNamespace|controller namespace]].
*
* If any of the above steps resolves into a controller, it is returned together with the rest
* part of the route which will be treated as the action ID. Otherwise, false will be returned.
*
* @param string $route the route consisting of module, controller and action IDs.
* 由模块、控制器和动作标识组成的路径。
* @return array|boolean If the controller is created successfully, it will be returned together
* with the requested action ID. Otherwise false will be returned.
* 如果控制器成功创建,将与被请求的操作标识一起返回,否则将返回false。
* @throws InvalidConfigException if the controller class and its file do not match.
* 如果控制器类及其文件不匹配,抛出异常
*/
public function createController($route)
{
if ($route === '') {//路径为空,调用默认的路径
$route = $this->defaultRoute;
} // double slashes or leading/ending slashes may cause substr problem
$route = trim($route, '/'); //去掉两边的反斜线,
if (strpos($route, '//') !== false) {
return false; //如果路径中包含双斜线,返回false
} if (strpos($route, '/') !== false) {
list ($id, $route) = explode('/', $route, );//将路径按反斜线分割为两个元素的数组,
} else {
$id = $route;
$route = '';
} // module and controller map take precedence 优先判断模块和控制器映射
if (isset($this->controllerMap[$id])) {
//如果$id是控制器ID,实例化控制器,返回控制器实例和后面的路径$route
$controller = Yii::createObject($this->controllerMap[$id], [$id, $this]);
return [$controller, $route];
}
$module = $this->getModule($id);
if ($module !== null) {//如果$id是模块ID,实例化控制器,返回控制器实例和后面的路径$route
return $module->createController($route);
} if (($pos = strrpos($route, '/')) !== false) {
//上面两种情况都不是,则表示还有子模块,构造子模块的标识
$id .= '/' . substr($route, , $pos);
$route = substr($route, $pos + );
} $controller = $this->createControllerByID($id);
if ($controller === null && $route !== '') {//实例化控制器 组装控制器实例和后面的路径$route
$controller = $this->createControllerByID($id . '/' . $route);
$route = '';
}
//存在返回控制器实例和后面的路径$route,否则返回false
return $controller === null ? false : [$controller, $route];
} /**
* Creates a controller based on the given controller ID.
* 根据给定的控制器标识创建控制器
* The controller ID is relative to this module. The controller class
* should be namespaced under [[controllerNamespace]].
* 当前模块的控制器标识,控制器类应在 [[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.
* 新创建的控制器实例,为null则控制器标识无效
* @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)
{
$pos = strrpos($id, '/');
if ($pos === false) {
$prefix = ''; //是否包含反斜线,
$className = $id;
} else {//将路径按反斜线分割为两个元素
$prefix = substr($id, , $pos + );
$className = substr($id, $pos + );
} if (!preg_match('%^[a-z][a-z0-9\\-_]*$%', $className)) {
return null;//正则判断是否符合规则
}
if ($prefix !== '' && !preg_match('%^[a-z0-9_/]+$%i', $prefix)) {
return null;
}
//组装控制器名
$className = str_replace(' ', '', ucwords(str_replace('-', ' ', $className))) . 'Controller';
$className = ltrim($this->controllerNamespace . '\\' . str_replace('/', '\\', $prefix) . $className, '\\');
if (strpos($className, '-') !== false || !class_exists($className)) {
return null; //控制器名有 ‘-’或不存在则为null
} if (is_subclass_of($className, 'yii\base\Controller')) {//检查对象是否有父类或子类
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.
* 当前模块的Action执行前调用的方法,将触发[[EVENT_BEFORE_ACTION]]事件
* The method will trigger the [[EVENT_BEFORE_ACTION]] event. The return value of the method
* will determine whether the action should continue to run.
* 如果返回true,Action方法才会执行
* 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);
$this->trigger(self::EVENT_BEFORE_ACTION, $event);//触发beforeAction事件
return $event->isValid;
} /**
* This method is invoked right after an action within this module is executed.
* 当前模块的Action执行后调用的方法,触发[[EVENT_AFTER_ACTION]]事件
* The method will trigger the [[EVENT_AFTER_ACTION]] event. The return value of the method
* will be used as the action return value.
* 如果返回true,后面的代码才会继续执行
* 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);
$event->result = $result;
$this->trigger(self::EVENT_AFTER_ACTION, $event);//触发beforeAction事件
return $event->result;
}
}

yii2源码学习笔记(十六)的更多相关文章

  1. yii2源码学习笔记(十四)

    Module类是模块和应用类的基类. yiisoft\yii2\base\Module.php <?php /** * @link http://www.yiiframework.com/ * ...

  2. yii2源码学习笔记(十九)

    view剩余代码 /** * @return string|boolean the view file currently being rendered. False if no view file ...

  3. yii2源码学习笔记(十二)

    继续了解controller基类. /** * Runs a request specified in terms of a route.在路径中指定的请求. * The route can be e ...

  4. yii2源码学习笔记(十)

    继续了解Application. /** * Registers the errorHandler component as a PHP error handler. * 注册errorHandler ...

  5. yii2源码学习笔记(十五)

    这几天有点忙今天好些了,继续上次的module来吧 /** * Returns the directory that contains the controller classes according ...

  6. async-validator 源码学习笔记(六):validate 方法

    系列文章: 1.async-validator 源码学习(一):文档翻译 2.async-validator 源码学习笔记(二):目录结构 3.async-validator 源码学习笔记(三):ru ...

  7. yii2源码学习笔记(九)

    Application是所有应用程序类的基类,接下来了解一下它的源码.yii2\base\Application.php. <?php /** * @link http://www.yiifra ...

  8. yii2源码学习笔记(八)

    Action是所有控制器的基类,接下来了解一下它的源码.yii2\base\Action.php <?php /** * @link http://www.yiiframework.com/ * ...

  9. 老刘 Yii2 源码学习笔记之 Action 类

    Action 的概述 InlineAction 就是内联动作,所谓的内联动作就是放到controller 里面的 actionXXX 这种 Action.customAction 就是独立动作,就是直 ...

随机推荐

  1. 【Caffe 测试】Training LeNet on MNIST with Caffe

    Training LeNet on MNIST with Caffe We will assume that you have Caffe successfully compiled. If not, ...

  2. [置顶] cocos2dx sqllite 增删查改等操作

    首先导入文件shell.c sqllite3.c sqlite3.h sqlite3etx.h文件(注意在生成安卓项目是 不要将shell.c写进android.mk文件中,写进去在cywin中生成会 ...

  3. getaccesstoken方法

    通过appid和appsecret获取access_token的定义函数 这里用的是memcache缓存存储用户信息7000秒 <?php function getAccessToken($ap ...

  4. jquery-data的三种用法

    1.jquery-data的用处 jQuery-data主要是用来存储数据,帮助普通对象或者jQuery对象来存储数据,其实如果单纯的储存dom的单一的属性,用attr自定义属性足够了:如果存储多个键 ...

  5. 应用程序无法正常启动0xc0150002 解决方式

        我也遇到过此问题,解决的方法: 方案一: 在项目的"属性|配置属性|链接器|常规"中的"启用增量链接"选择"否".此方法阻断了问题产 ...

  6. Excel异常Cannot get a text value from a numeric cell

    POI操作Excel时数据Cell有不同的类型,当我们试图从一个数字类型的Cell读取出一个字符串并写入数据库时,就会出现Cannot get a text value from a numeric ...

  7. Google Map API v2 (四)----- 导航路径

    仍然是建议个异步小任务 private GetPathTask mGetPathTask = null; private void getGuidePath(LatLng origin){ if(mG ...

  8. app抓包

    http://www.360doc.com/content/14/1126/11/9200790_428168701.shtml 记得下载证书  不然有些网站是抓不到的

  9. DataGridView编辑实时生效和索引-1没有值问题

    1. 问题:DataGridView单元格编辑后,只有离开焦点时,编辑的内容才会生效(在绑定的DataSource中生效).  使用 this.dataGridView1.CommitEdit(Dat ...

  10. CI框架篇之基础篇(2)

    CodeIgniter 的基础了解了后,现在就来对这个框架进行预热 CodeIgniter 配置 理论是不用配置,直接拷贝到服务器目录下即可运行 CodeIgniter 安装分为四个步骤: 1. 解压 ...