vendor/yiisoft/yii2/base/Module. php(续)
/** * 检索指定的子模块ID. * 这种方法支持检索两个子模块和子模块. * @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(区分大小写)。检索子模块 $module = $this->getModule(substr($id, 0, $pos)); //判断是否加载 return $module === null ? null : $module->getModule(substr($id, $pos + 1), $load); } if (isset($this->_modules[$id])) { //判断$id是否存在 if ($this->_modules[$id] instanceof Module) { return $this->_modules[$id]; } elseif ($load) { Yii::trace("Loading module: $id", __METHOD__); //通过返回类来查看$id $module = Yii::createObject($this->_modules[$id], [$id, $this]); $module->setInstance($module); return $this->_modules[$id] = $module; } } //不存在返回null 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 followings: * * - 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; } } /** * 注册子模块在当前模块. * * 每个子模块应该指定为一个名称-值对 * 名称是指模块和价值模块的ID或配置 * array that can be used to create the module. In the latter case, [[Yii::createObject()]] * will be used to create the module. * * 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; } } /** * 该方法解析指定的路线和创建相应的子模块(s),控制器和行动 * 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. * 如果路径为空,该方法将使用[[defaultRoute]] * @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 = []) { // 创建controller,获取controller的实例和action的ID $parts = $this->createController($route); if (is_array($parts)) { /* @var $controller Controller */ list($controller, $actionID) = $parts; // 保留下app中绑定的controller $oldController = Yii::$app->controller; // 将当前controller绑定到app上 Yii::$app->controller = $controller; $result = $controller->runAction($actionID, $params); // 还原会app之前的绑定的controller Yii::$app->controller = $oldController; return $result; } else { $id = $this->getUniqueId(); throw new InvalidRouteException('Unable to resolve the request "' . ($id === '' ? $route : $id . '/' . $route) . '".'); } }