前言

我个人觉得在当前 MVC 流行的架构下,要想去了解一个框架,或者是一个基于此架构下的应用程序,最好的入手方式就是先看路由,虽然路由不是 MVC 里的任何一个,但是知道了路由的来龙去脉就知道了整个框架或者是应用的结构。从一个请求开始,具体分配到哪个 C 去执行的, C 里又调用了哪些东西,整个脉络也就清晰了。

然而整个路由的实现的逻辑本身又是比较好理解的,无非就是从请求的 URL 中按着约定的规则取出 C 对应的 class 以及 method 即可。如此,我们接下来详细看看 CI 4 dev 版的路由具体实现的逻辑。

找到路由逻辑的具体位置

上一节我们说 Codeigniter.php 的时候讲到, index.php 入口文件通过 $app->run() 调取了 Codeigniter 类中的 run 方法。 run 中又执行了 handleRequest 方法用来处理请求的具体信息。接着 handleRequest 调取 tryToRouteIt 来尝试解析路由,此时代码逻辑还在 Codeigniter.php 里,真正的解析过程还没有开始。在 tryToRouteIt 方法中,通过 service 方式加载了 router 类,通过 system/config/service 加载 router 代码如下,这也是一个服务加载的统一形式,其它的核心辅助类都是如此加载:

public static function router(\CodeIgniter\Router\RouteCollectionInterface $routes = null, $getShared = true)
{if ($getShared){return self::getSharedInstance('router', $routes);}if (empty($routes)){$routes = self::routes(true);}return new \CodeIgniter\Router\Router($routes);
}

从 倒数第二行可以看出加载的 router 类位于 system/router 下的 Router 类里。

system/router/Router.php 解析路由的详细过程

首先我们把 Codeigniter.php 中调用该类的详细代码列出来如下:

$this->controller = $this->router->handle($path);
$this->method     = $this->router->methodName();

关键的只有两行,一行找类一行找方法。找类的那一行处理了大部分的逻辑,找方法的那一行就是简单的 get 。

  1. 146-150 行,判断 $uri 如果为空,那么返回默认路由。因为在该类的构造方法里读取了配置中的默认路由,因此此处直接返回配置即可。

  2. 153-156 行,检查路由配置文件里的配置是否有和当前匹配的 URL ,有的话,直接返回配置的控制器即可。

  3. 161-164 行,检查是否开启了自动路由匹配,如果没有开启,那么读取完配置好的路由都没有结果,那么就可以 throw pageNoteFoundException 了。

  4. 166 行,真正的处理 CI 路由逻辑的地方。详细见 autoRoute 方法。

  5. 168 行,把处理完毕后找到的 controller 返回。

此方法通过调用其它方法已经实现了寻找 controller 的过程,主流程到此已经结束。

autoRoute 方法

该方法是自动按着约定规则去 controller 目录去找路由的过程。

  1. 442 行:将 URI 按着 / 打散成数组。

  2. 444 行:确定 URI 里是否包含 Controller 的目录部分。该方法将 $segments 数组由 0 元素一次一次循环并匹配 application/controller 下的目录,找到后并且该目录下没有同名的 PHP 文件即认为是路径组成部分,同时将该元素从 $segments 中去除,以保证 $segments 中剩下的仅仅是 class 与 method 内容。

  3. 448-456 行:去除路径后发现 $segments 数组没元素啦,那么只能是默认处理了。否则直接弹出数组中的第一个元素即是 class 信息。

  4. 461-464 行:如果此时 $segments 中不为空,那么弹出数组中第一个元素是 method 信息。

  5. 466-469 行:如果此时 $segments 中还不为空,那么剩下的就是传递的参数信息。

  6. 472-476 行:判断代表 controller 的文件存在的话 include 进来。

小结

至此,路由部分处理完了,找到的 controller 与 method 信息分别放到了对象对应的属性里。因此在 codeigniter.php 中用以下两行就拿到了相应的信息:

$this->controller = $this->router->handle($path);
$this->method     = $this->router->methodName();

下一章应该会看看 CI 4 相对 CI 3 的变化。

此文可以转载,但转载前需要发邮件到imustgxd*sina.cn进行沟通,未沟通的均视作侵权。 转载同时需注明原文链接
(https://segmentfault.com/a/11...,并保留此段文字。

Codeigniter 4.0-dev 版源码学习笔记之四——详细路由过程相关推荐

  1. Codeigniter 4.0-dev 版源码学习笔记之六——控制器

    前言 其实一开始我是很纠结是否要写控制器的源码分析的,因为控制器的源码太少了,少到你不相信这是一个 MVC 里的一个重头.直觉里,大家都觉得控制器作为各个请求的"入口",其后端应该 ...

  2. Vuex 4源码学习笔记 - 通过Vuex源码学习E2E测试(十一)

    在上一篇笔记中:Vuex 4源码学习笔记 - 做好changelog更新日志很重要(十) 我们学到了通过conventional-changelog来生成项目的Changelog更新日志,通过更新日志 ...

  3. Vuex 4源码学习笔记 - Vuex是怎么与Vue结合?(三)

    在上一篇笔记中:Vuex源码学习笔记 - Vuex开发运行流程(二) 我们通过运行npm run dev命令来启动webpack,来开发Vuex,并在Vuex的createStore函数中添加了第一个 ...

  4. PHP Yac cache 源码学习笔记

    YAC 源码学习笔记 本文地址 http://blog.csdn.net/fanhengguang_php/article/details/54863955 config.m4 检测系统共享内存支持情 ...

  5. Java多线程之JUC包:Semaphore源码学习笔记

    若有不正之处请多多谅解,并欢迎批评指正. 请尊重作者劳动成果,转载请标明原文链接: http://www.cnblogs.com/go2sea/p/5625536.html Semaphore是JUC ...

  6. RocketMQ 源码学习笔记 Producer 是怎么将消息发送至 Broker 的?

    RocketMQ 源码学习笔记 Producer 是怎么将消息发送至 Broker 的? 文章目录 RocketMQ 源码学习笔记 Producer 是怎么将消息发送至 Broker 的? 前言 项目 ...

  7. 雷神FFMpeg源码学习笔记

    雷神FFMpeg源码学习笔记 文章目录 雷神FFMpeg源码学习笔记 读取编码并依据编码初始化内容结构 每一帧的视频解码处理 读取编码并依据编码初始化内容结构 在开始编解码视频的时候首先第一步需要注册 ...

  8. Apache log4j-1.2.17源码学习笔记

    (1)Apache log4j-1.2.17源码学习笔记 http://blog.csdn.net/zilong_zilong/article/details/78715500 (2)Apache l ...

  9. Vuex 4源码学习笔记 - 通过dispatch一步步来掌握Vuex整个数据流(五)

    在上一篇笔记中:Vuex 4源码学习笔记 - Store 构造函数都干了什么(四) 我们通过查看Store 构造函数的源代码可以看到主要做了三件事情: 初始化一些内部变量以外 执行installMod ...

最新文章

  1. 九降风之曾经的岁月 永远的兄弟 一块硬盘的爱情
  2. rebar Erlang构建工具(转)
  3. mysql数据通讯方式_c# 与 Mysql 的通讯方式总结
  4. 新闻系统查询思路和步骤
  5. python写ui自动化测试用例_自动化测试(6) | Web UI 自动化测试方案
  6. 微信小程序 调用地图接口,实现定位
  7. html鼠标离开点击停留,Javascript DOM事件操作小结(监听鼠标点击、释放,悬停、离开等)...
  8. 右键菜单显示项的可见度控制 c# 1614605595
  9. 循环 Request.ServerVariables
  10. sql中exists,Intersect ,union 与union All的用法
  11. vue element隐藏组件滚动条scrollbar使用
  12. Spring Cloud与微服务学习总结(8)——Spring Boot、微服务架构和大数据治理三者之间的故事
  13. 仿Android6.0联系人列表
  14. WM_NOTIFY的使用
  15. AppCompat是什么?
  16. CCNA中文版完整教程
  17. excel一列求和_Excel六层心法
  18. c语言(http://c.biancheng.net/view/1714.html)
  19. MTK MT6169 2G用户指南参考资料
  20. iOS 一个错误 Unable to find a specification for

热门文章

  1. 2017-05-12-Linux文件操作
  2. 关于JS中的定时器!!!
  3. UIScrollView实现不全屏分页的小技巧
  4. POJ 1797 Heavy Transportation 解题报告
  5. Idea新建modules后无法自动导入pom.xml
  6. angular 加入原生html,Angular HTML绑定
  7. android java 指针,opencv android:向我的代码中添加cascade分类器后出现空指针异常
  8. 类加载器子系统的作用
  9. 程序人生:给年轻程序员关于开发过程的10条忠告
  10. ASP.NET MVC的过滤器笔记