Yii源码阅读笔记(二十四)
Module类中获取子模块,注册子模块,实例化控制器,根据路由运行指定控制器方法的注释:
/** * Retrieves the child module of the specified ID. * 取出指定模块的子模块 * This method supports retrieving both child modules and grand child modules. * 该方法支持检索子模块和子模块的子模块 * @param string $id module ID (case-sensitive). To retrieve grand child modules, * use ID path relative to this module (e.g. `admin/content`). * @param boolean $load whether to load the module if it is not yet loaded. * @return Module|null the module instance, null if the module does not exist. * @see hasModule() */ public function getModule($id, $load = true) { if (($pos = strpos($id, '/')) !== false) {//判断模块id格式是否为 `admin/content` // sub-module $module = $this->getModule(substr($id, 0, $pos));//取子模块 return $module === null ? null : $module->getModule(substr($id, $pos + 1), $load);//子模块不为空,返回子模块的子模块,否则返回空 } if (isset($this->_modules[$id])) { if ($this->_modules[$id] instanceof Module) { return $this->_modules[$id];//如果_modules数组中有该模块,直接返回该模块 } elseif ($load) {//否则,$load为真,先实例化后返回 Yii::trace("Loading module: $id", __METHOD__); /* @var $module Module */ $module = Yii::createObject($this->_modules[$id], [$id, $this]); $module->setInstance($module); return $this->_modules[$id] = $module; } } //不存在,返回空 return null; } /** * Adds a sub-module to this module. * 为当前模块添加子模块 * @param string $id module ID * @param Module|array|null $module the sub-module to be added to this module. This can * be one of the following: * * - a [[Module]] object * 一个模块对象 * - a configuration array: when [[getModule()]] is called initially, the array * will be used to instantiate the sub-module * 模块参数为配置数组,用于实例化模块 * - null: the named sub-module will be removed from this module * 为空,则表示删除 */ public function setModule($id, $module) { if ($module === null) { unset($this->_modules[$id]); } else { $this->_modules[$id] = $module; } } /** * Returns the sub-modules in this module. * 返回该模块的子模块 * @param boolean $loadedOnly whether to return the loaded sub-modules only. If this is set false, * then all sub-modules registered in this module will be returned, whether they are loaded or not. * Loaded modules will be returned as objects, while unloaded modules as configuration arrays. * @param boolean $loadedOnly 可选参数,定义是否只返回已加载的子模块 * @return array the modules (indexed by their IDs) */ public function getModules($loadedOnly = false) { if ($loadedOnly) { $modules = []; foreach ($this->_modules as $module) { if ($module instanceof Module) { $modules[] = $module; } } return $modules; } else { return $this->_modules; } } /** * 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. * 如果ID相同,后者会覆盖前置 * * The following is an example for registering two sub-modules: * * ```php * [ * '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;//将对象交给Yii::$app->controller 这里面起的作用应该是运行控制器,最后释放控制器的对象变量 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. * @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 //双斜线或者开始/结束的斜线会引起函数问题,去掉两边的斜线,如果路径中包含双斜线,返回false $route = trim($route, '/'); if (strpos($route, '//') !== false) { return false; } if (strpos($route, '/') !== false) {//路径中包含斜线 list ($id, $route) = explode('/', $route, 2);//将路径按斜线分割为两个元素的数组,[0]为$id,[1]为$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);//如果$id是模块ID,实例化控制器,返回控制器实例和后面的路径$route if ($module !== null) { return $module->createController($route);//调用自身实例化控制器,返回控制器实例和后面的路径$route } if (($pos = strrpos($route, '/')) !== false) {//上面两种情况都不是,则表示该模块还有子模块,构造子模块的id $id .= '/' . substr($route, 0, $pos); $route = substr($route, $pos + 1); } $controller = $this->createControllerByID($id);//调用createControllerByID()方法实例化控制器 if ($controller === null && $route !== '') { $controller = $this->createControllerByID($id . '/' . $route); $route = ''; } return $controller === null ? false : [$controller, $route];//实例化成功返回控制器实例和后面的路径$route,失败返回false }
Yii源码阅读笔记(二十四)的更多相关文章
- Yii源码阅读笔记(十四)
Model类,集中整个应用的数据和业务逻辑——场景.属性和标签: /** * Returns a list of scenarios and the corresponding active attr ...
- Yii源码阅读笔记(十二)
Action类,控制器中方法的基类: namespace yii\base; use Yii; /** * Action is the base class for all controller ac ...
- Yii源码阅读笔记(十八)
View中的查找视图文件方法和渲染文件方法 /** * Finds the view file based on the given view name. * 通过view文件名查找view文件 * ...
- Yii源码阅读笔记(十五)
Model类,集中整个应用的数据和业务逻辑——验证 /** * Returns the attribute labels. * 返回属性的标签 * * Attribute labels are mai ...
- Yii源码阅读笔记(十六)
Model类,集中整个应用的数据和业务逻辑—— /** * Generates a user friendly attribute label based on the give attribute ...
- Yii源码阅读笔记(十)
控制器类,所有控制器的基类,用于调用模型和布局,输出到视图 namespace yii\base; use Yii; /** * Controller is the base class for cl ...
- Yii源码阅读笔记(十九)
View中渲染view视图文件的前置和后置方法,以及渲染动态内容的方法: /** * @return string|boolean the view file currently being rend ...
- Yii源码阅读笔记(二)
接下来阅读BaseYii.php vendor/yiisoft/yii2/BaseYii.php—— namespace yii; use yii\base\InvalidConfigExceptio ...
- Yii源码阅读笔记(一)
今天开始阅读yii2的源码,想深入了解一下yii框架的工作原理,同时学习一下优秀的编码规范和风格.在此记录一下阅读中的小心得. 每个框架都有一个入口文件,首先从入口文件开始,yii2的入口文件位于we ...
- werkzeug源码阅读笔记(二) 下
wsgi.py----第二部分 pop_path_info()函数 先测试一下这个函数的作用: >>> from werkzeug.wsgi import pop_path_info ...
随机推荐
- 去除手机端a标签等按下去背景色
a,button,input,textarea,label,i,em{/*highlight*/ -webkit-tap-highlight-color: rgba(255,0,0,0); borde ...
- sprint3冲刺第一天
1.计划了sprint3要做的内容: 整合前台和后台,然后发布让用户使用,然后给我们反馈再进行改进 2.backlog表格: ID 任务 Est 做了什么 1 实现用户登录与权限判定 4 进行用户分类 ...
- Codeforces 581F Zublicanes and Mumocrates(树形DP)
题目大概说有一棵树要给结点染色0或1,要求所有度为1的结点一半是0一半是1,然后问怎么染色,使两端点颜色不一样的边最少. dp[0/1][u][x]表示以u结点为根的子树中u结点是0/1色 且其子树有 ...
- R AnalyticFlow---R的流程图
0.简介 R AnalyticFlow是一款利用R环境作为统计计算的数据分析软件,创作者是日本人,版权属于日本Ef-prime公司.R AnalyticFlow除了拥有直观的用户界面和流程图显示,它还 ...
- oralce CASE WHEN 用法
如何将时间日期分隔成“上半月”“下半月” select ( THEN '上半月' THEN '下半月' ELSE 'NULL' END) AS mon from BFBHDD8.SKTXSJL
- wamp 2.5 开放访问权限和设置虚拟域名
开放访问权限 D:\wamp\bin\apache\apache2.4.9\conf 里的 httpd.conf 搜索www 把 Require local 改为 Require all gra ...
- POJ 1222 (开关问题+高斯消元法)
题目链接: http://poj.org/problem?id=1222 题目大意:一堆开关,或开或关.每个开关按下后,周围4个方向开关反转.问使最后所有开关都关闭的,开关按法.0表示不按,1表示按. ...
- 20145304 Java第六周学习报告
20145304<Java程序设计>第六周学习总结 教材学习内容总结 1.InputStream与OutputStream: 在Java中,输入串流的代表对象为java.io.InputS ...
- HTML5中video 和 ogg
HTML5中 的ogg 从网上学习HTML5之video时看到了下面的代码,不太清楚ogg是什么,于是搜索了一些知识点供了解.
- [CareerCup] 18.3 Randomly Generate Integers 随机生成数字
18.3 Write a method to randomly generate a set of m integers from an array of size n. Each element m ...