老刘 Yii2 源码学习笔记之 Module 类
2018-12-13 16:36 掸尘 阅读(233) 评论(0) 编辑 收藏 举报关系类图
从上图可以看出 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
- 第一次递归会把路由字符串的 forum 过滤掉,还剩 admin/default/index
- 第二次 default/index
- 第三次 由于default不是Module, 通过Module的 init 方法知道当时的命名空间,所以就可以推断出Controller位置
总结
Module 的 getModule 方法 和 createController 方法 都是通过递归调用,层层剥离,设计精巧、简洁。