前言我个人认为在目前流行的MVC架构下,如果想了解一个框架,或者基于该架构的应用,最好是最好的开始方法是先查看路由。虽然路由不是任何的MVC,但是知道了路由的来龙去脉就知道整个框架或者说应用的结构了。从一个请求开始,分配给哪个C执行,C中调用了什么,整个上下文就很清楚了。不过整个路由实现的逻辑本身还是比较容易理解的。无非就是按照约定的规则从请求的URL中提取出C对应的类和方法。这样,我们就来详细了解一下CI4dev版本中路由的具体实现逻辑。找到路由逻辑的具体位置。上一节讲到Codeigniter.php时,index.php入口文件通过$app->run()调用了Codeigniter类中的run方法。run中执行handleRequest方法,处理请求的具体信息。然后handleRequest调用tryToRouteIt尝试解析路由。此时代码逻辑还在Codeigniter.php中,真正的解析过程还没有开始。在tryToRouteIt方法中,通过service方法加载路由器类,通过system/config/service加载路由器代码如下,也是一种统一的服务加载形式,其他核心辅助类加载方式如下:publicstaticfunctionrouter(\CodeIgniter\Router\RouteCollectionInterface$routes=null,$getShared=true){if($getShared){returnself::getSharedInstance('router',$routes);}}if(empty($routes)){$routes=self::routes(true);}returnnew\CodeIgniter\Router\Router($routes);}从倒数第二行可以看出加载的路由器类位于system/router下的Router类中。system/router/Router.php解析路由的详细过程首先我们在Codeigniter.php中列出调用该类的详细代码如下:$this->controller=$this->router->handle($path);$this->method=$this->router->methodName();关键只有两行,一行找类,一行找方法。查找类的那一行处理大部分逻辑,查找方法的那一行只是get。第146-150行,如果判断$uri为空,则返回默认路由。因为配置中的默认路由是在该类的构造函数中读取的,所以这里可以直接返回配置。第153-156行,检查路由配置文件中的配置是否有与当前匹配的URL,如果有则直接返回配置的controller。第161-164行,检查路由自动匹配是否开启。如果不启用,读取配置的路由后没有结果,则可以抛出pageNoteFoundException。第166行是处理真正的CI路由逻辑的地方。有关详细信息,请参阅autoRoute方法。第168行返回处理后找到的控制器。该方法实现了调用其他方法查找controller的过程,至此主流程结束。autoRoute方法该方法是按照约定的规则自动去controller目录下寻找路由的过程。第442行:根据/将URI打散成数组。第444行:判断URI是否包含Controller的目录部分。该方法从0个元素开始逐一循环$segments数组,匹配application/controller下的目录。如果找到并且该目录下没有同名的PHP文件,则认为它是一个路径组成部分,将这个元素从$segments中移除,以确保$segments的其余部分只有类和方法内容。第448-456行:去掉路径后发现$segments数组没有元素,只能默认处理。否则,弹出数组中的第一个元素是类信息。第461-464行:如果此时$segments不为空,则popup数组的第一个元素为方法信息。第466-469行:如果此时$segments不为空,剩下的就是传递的参数信息。第472-476行:如果判断代表控制器的文件存在,则包含它。总结至此,路由部分已经处理完毕,将找到的controller和method信息分别放在对象对应的属性中。所以在codeigniter.php中使用下面两行获取相应的信息:$this->controller=$this->router->handle($path);$this->method=$this->router->methodName();下一章应该看看CI4相对于CI3的变化。本文可以转载,但转载前需要发邮件至imustgxd*sina.cn进行交流,未交流的将被删除视为侵权。转载时必须注明原文链接(https://segmentfault.com/a/11...),并保留此段文字。
