vendor/yiisoft/yii2/base/Module. php(续)
/** * 新建一个控制器实例基于给定的路线. * * 路线应该是相对于这个模块。该方法实现了以下算法 * 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 `abcDefController` * or `abcdefXyzController` 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 // 如果有双斜线或者结束的斜线,可能会引起问题 $route = trim($route, '/'); if (strpos($route, '//') !== false) { return false; } if (strpos($route, '/') !== false) { // 如果存在斜线,就根据斜线分割route,并限制最多分割成两个 list ($id, $route) = explode('/', $route, 2); } else { // 不存在,就直接赋值给$id $id = $route; $route = ''; } // module and controller map take precedence if (isset($this->controllerMap[$id])) { // 如果controllerMap中存在相应的$id,就使用Yii::createObject去创建该controller的实例 $controller = Yii::createObject($this->controllerMap[$id], [$id, $this]); return [$controller, $route]; } // 根据id获取module $module = $this->getModule($id); if ($module !== null) { // 获取到module,就递归调用相应module的createController去创建controller的实例 return $module->createController($route); } // 如果取到了module,就需要继续去取controller的ID // 再次根据斜线分割 if (($pos = strrpos($route, '/')) !== false) { // 如果有斜线,就将module的ID和后面截取出的内容一起拼成ID $id .= '/' . substr($route, 0, $pos); // 剩余的赋给route $route = substr($route, $pos + 1); } // 然后根据ID去创建controller的实例 $controller = $this->createControllerByID($id); // 未创建成功,并且route不为空 if ($controller === null && $route !== '') { // 将route拼接到ID中,再次去创建controller出的实例 $controller = $this->createControllerByID($id . '/' . $route); $route = ''; } return $controller === null ? false : [$controller, $route]; }