学习yii2.0框架阅读代码(十九)

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' => 'appmodulescommentCommentModule',
     *         'db' => 'db',
     *     ],
     *     'booking' => ['class' => 'appmodulesookingBookingModule'],
     * ]
     * ~~~
     *
     * @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) . '".');
        }
    }
原文地址:https://www.cnblogs.com/xwzj/p/5453664.html