liuzhang 2018-12-13 15:52:51 3673次浏览 0条评论 0 1 0

类图

未命名文件 (2).png

从上图可以看出 Application 类继承了 Module,在框架中的是非常重要角色。

加载配置

public function setModules($modules)
{
    foreach ($modules as $id => $module) {
        $this->_modules[$id] = $module;
    }
}

base\Module 通过 setModules 把 Module 配置信息加载进来,赋值给 私有变量 _modules。

解析路由

Module 还有一个重要的功能,就是找到路由中的 Controller

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) {
        list($id, $route) = explode('/', $route, 2);
    } else {
        $id = $route;
        $route = '';
    }

    // module and controller map take precedence
    if (isset($this->controllerMap[$id])) {
        $controller = Yii::createObject($this->controllerMap[$id], [$id, $this]);
        return [$controller, $route];
    }
    $module = $this->getModule($id);
    if ($module !== null) {
        return $module->createController($route);
    }

    if (($pos = strrpos($route, '/')) !== false) {
        $id .= '/' . substr($route, 0, $pos);
        $route = substr($route, $pos + 1);
    }

    $controller = $this->createControllerByID($id);
    if ($controller === null && $route !== '') {
        $controller = $this->createControllerByID($id . '/' . $route);
        $route = '';
    }

    return $controller === null ? false : [$controller, $route];
}

这个函数通过递归调用。假如路由是这样的:forum/admin/default/index

  1. 第一次递归会把路由字符串的 forum 过滤掉,还剩 admin/default/index
  2. 第二次 default/index
  3. 第三次 由于 default 不是 Module, 通过 Module 的 init 方法知道当时的命名空间,所以就可以推断出 Controller 位置。

总结

Module 的 getModule 方法 和 createController 方法 都是通过递归调用,层层剥离,设计精巧、简洁。

觉得很赞
    没有找到数据。
您需要登录后才可以评论。登录 | 立即注册