插件窝 干货文章 ThinkPHP检测URL路由深度解析

ThinkPHP检测URL路由深度解析

margin bottom padding 编辑器 905    来源:    2024-10-27

前言

由于文章篇幅的原因,执行在新开一篇文章进行写。

在上一篇中给大家讲解了以下内容。

  • 路由初识化简单分析
  • 通过定义路由再谈门面
  • 路由定义rule方法中的$this->group到底执行了什么
  • 路由规则预处理
  • 解析生成路由标识的快捷访问

但是在路由这块还有很多的内容要来讲解,接下来就会针对以下内容进行解析。

  • 路由配置(就是在route文件中的return中)
  • dispatch初认识
  • route-check 检测URL路由
  • 。。。。。。。。。。。。。

接下来就一个一个进行详解。

同样给大家放一个关于路由的执行图,供大家进行参考。

路由的执行流程

一、dispatch初认识以及route-check 检测URL路由

这块的内容是在执行应用程序里边,接下来咔咔带大家简单的认识一下。

本节没有源码的解释,只是为了后文坐铺垫使用的,所以很有必要知道dispatch是怎么一个回事。

下图就是在执行完路由初始化之后返回上层继续执行的流程。

然后就会执行到路由检测这里。

image.png
dispatch初始执行位置

路由测试使用如下图

image.png
路由测试使用案例

然后我们可以对这个调度信息进行打印

image.png
打印数据
image.png
打印结果

在上图中已经打印出了关于dispatch的相关的值

接下来就会针对routeCheck方法进行简单的预览

image.png
routeCheck

在上图方法中只要明确在这一步会处理缓存,并且返回一个Dispatch对象即可。

这块的源码大家可以简单的看一下即可,不是很重要。

route-check 检测URL路由

但是这块的内容还是需要简单的去看一下的。

在看之前需要明确一下传入的俩个参数分别是什么。

参数一:路由规则 参数二:检测是否配置了强制路由

image.png
返回一个dispatch对象

知道了参数的含义后就需要去到check这个方法中一探究竟了。

image.png
检测url路由

在这个方法中关于自动检测域名路由我们来打印一下数据是什么样的。

其实这个返回的结果就是跟之前资源路由挂载的方式是一样的,

image.png
打印结果

然后会通过pathinfo分隔符 : 把url中的 / 改为 |

并且会在配置文件获取路由是否完全匹配

最终执行使用默认路由解析

这里边的细节就不去深度解析了,关于路由这块的细节是在是太多了,如果一个一个去针对细节,那是需要耗费大量的时间的。

所以这块的内容就到这里了,只需要知道执行了什么,并且最终返回的是什么即可。

二、request类是如何找到的

在上一节中$result = $domain->check($this->request, $url, $completeMatch);会执行这一块的内容。

这里不去关心这个方法执行了什么。

而是需要关心这个$this->request是如果找到并且执行的。

首先可以看到的是在Route类中是存在request这个属性的。

image.png
请求对象的属性

接着来到Route的构造函数,在这里你会发现新天地。

此处使用了ArrayAccess像数组一样访问对象,但是$app中不存在request属性,所以就会去执行容器类中的__get魔术方法,在__get方法中调用的是容器中的make方法,第一个参数为request,最终会返回request的实例。

image.png
构造函数

这里的$app其实就是通过依赖注入进来的App实例。

看了这么多的源码肯定知道App类是继承Container类的也就是容器类。

在容器类中得最下边会有几个魔术方法。

这里只需要关注__get方法即可。

image.png
魔术方法

__get方法会在访问不存在的属性时会执行的函数。

也就说最终会执行到make方法。

image.png
容器类中的make方法

这个方法会通过一系列的操作,最终返回一个Request的实例。

并且把这个实例存放到容器里边,下次使用时直接获取即可。

关于容器类中的make方法是容器类中特别重要的方法,也是灵魂方法。

全框架的实例都是通过容器返回的,所以说这个方法的重要性就不用咔咔在多说了。

咔咔之前对容器进行过特别深入的理解,并且用文章的形式呈现给了大家。

三、检测域名路由

先给大家把流程图画出来,然后根据流程跟这咔咔的节奏即可。

image.png
路由域名检测流程图

首先要确认的一件事情就是检测域名路由是在执行应用程序中执行的。

上层执行流程就是在入口文件哪里。

image.png
执行应用程序

首先代码会执行到routeCheck这个方法里边,那么就先看这个文件。

先看注释,对这个方法的解释就是URL路由检测。

在这个方法里边先是会对路由缓存进行检测,这块内容就是关于Cache的。

在这个方法里边最重要的的就是路由检测 返回一个Dispatch对象就是这个方法。

image.png
URL路由检测

那么接下里就是看这个方法。

首先要明确的就是传进去的俩个参数都是什么。

  • $path : string(4) "blog"
  • $must : bool(false)
image.png
路由检测

在检测URL路由中会做以下几件事情。

  • pathinfo分隔符 : 把url中的 / 改为 |
  • 路由是否完全匹配
  • 检测域名路由
  • 默认路由解析

接下来就只需要对检测域名路由流程进行深度解析。

关于前俩个执行只是一些字符串的处理,看看就行,知道最终返回什么即可。

image.png
检测URL路由

同样在检测域名路由的执行中明确三个参数的含义。

  • $this->request : 通过容器类的__get魔术方法,执行容器类的make方法,最终返回request的实例对象,这列不会的去看第六节的文章
  • $url : string(4) "blog"
  • $completeMatch : 路由是否完全匹配

来到$result = $domain->check($this->request, $url, $completeMatch);这里,也就是本节的重点了。

在这个方法里边会执行以下几个流程,会针对重要的执行流程进行深度解析。

  • 检测路由别名 : checkRouteAlias
  • 检测URL绑定:checkUrlBind
  • 判断路由参数
  • 添加域名中间件
  • 检测分组路由 : parent::check
image.png
检测域名路由

检测路由别名 : checkRouteAlias

参数解释

  • $request : request类的实例
  • $url : 传过来的 blog

在这个方法里边存在俩个需要明确的知识点

  • strpos : 查找在字符串中第一次出现的位置
  • strstr : strstr返回一个指针,指向string2在string1中首次出现的位置,strstr("Helloworld!","world");?>\n输出:\nworld!
  • 首先会对URL地址进行处理:返回blog
  • 获取别名路由定义  NULL
  • 以资源路由blog为例 返回false
image.png
检测路由别名

在检测路由别名中存在一个方法需要去在看一下

参数就是上图中传入的blog

image.png
获取别名路由定义

来到这个方法,首先要明确的事情就是此方法在类thinkphp/library/think/Route.php中

并且此类使用了think\route下的所有类

这个方法就会把从检测路由过来的blog然后会在Route类中的alias属性里边进行获取,如果不存在则会返回NULL

这个别名的使用会在下文中提到

image.png
获取别名路由定义

来到检测别名路由的最后return $item ? $item->check($request, $url) : false;也就是这行代码,从上图中就可以知道,这个item就是NULL

并且最终将这个NULL给返回回去。

检测URL绑定:checkUrlBind

参数说明

  • $request : request类的实例
  • $url : 传过来的 blog

在这个方法中只对下图咔咔圈出来的地方进行详解。

image.png
检测URL绑定

来到方法getBind读取路由绑定,可以看到咔咔已经将传入的参数打印出来了。

本方法是在thinkphp/library/think/route/Domain.php这个类里边,还记得在设置路由规则的$This->group就是使用的这个类,不知道的可以去看路由文章的第一节。

同时在这个方法中会进行一次subDomain当前子域名的获取。

在这个方法最终会返回www,主要看一下圈出来的第一个部分。

通过request类中的host方法来获取当前域名,然后进行分割。

返回数据:array(1) { [0] =>\n string(3) "www"\n}

给子域名赋值:$this->subDomain

返回最终结果返回子域名 : www

image.png
获取当前子域名

接着就会返回到上层,在上层进行判断获取的当前子域名WWW。

一些是所有的判断处理,第一个判断肯定是不会成立的,因为只返回了www,并没有.

下边的判断是根据路由绑定进行的判断,这里只需要知道最总会返回NULL就可以了。

image.png
进行的判断

知道了在底层返回了NULL,所以在这里的判断同样也不会成立,所以最终给上层返回的结果就是false。

image.png
检测URL绑定

判断路由参数

根据上图执行流程最终还是会返回到thinkphp/library/think/route/Domain.php这个方法check检测域名路由。

然后开始进行判断路由参数。

没有路由参数跳过不执行。

存在路由参数:执行方法setRouteVars :设置路由变量  这个参数是在框架版本5.1.5以上才可以使用,由于咔咔使用的版本有点低,就不对其详解了。

image.png
检测域名路由
image.png
文档

添加域名中间件

关于中间件这里也不对其进行解释,因为后期会新开一篇文章来详解,本文还是以路由为重点哈!

检测分组路由

接着就会来到检测域名路由的最后一个流程,执行代码return parent::check($request, $url, $completeMatch);

会跳转到类文件:thinkphp/library/think/route/RuleGroup.php,因为Domain类是继承RuleGroup这个类的。

参数说明

  • $request : request类的实例
  • $url : 传过来的 blog
  • $completeMatch : 路由是否完全匹配

在这个方法中咔咔只会对这里的其中的一个流程进行详解,也就是合并分组参数。

因为这个方法也是贯穿执行流程的一条主线,其余的都是方法都是在进行检测,判断。

image.png
合并分组参数

四、总结

关于路由用了俩篇文章还没有结束,看了这么长时间的源码也就是路由这块是最复杂并且最难理解的。

其中的类是一环套一环,路由先暂时了解到这里,后期在阅读其它源码时在进行其它内容补充。

在路由这一篇中主要执行的流程图大家一定要仔细看。

image.png
执行流程图

在就是通过在注册路由规则时的group这个属性最终返回的是Domain类,这里的内容一定要清晰。

主要知道在路由中域名的配置流程,域名是在何时进行配置的。

路由文件中的返回数组和在导入路由文件流程要有清晰的思路。

再就是回顾之前学习的ArrayAccess,像访问数组一样访问对象。

容器中的魔术方法__get方法,在这个魔术方法中存在make方法,主要用来返回一个类的实例,并且存放到容器中。

关于路由的方面暂时就说到这里的,预计在有一篇就会把路由写完了。

坚持学习、坚持写博、坚持分享是咔咔从业以来一直所秉持的信念。希望在诺大互联网中咔咔的文章能带给你一丝丝帮助。我是咔咔,下期见。

            前言一、dispatch初认识以及route-check 检测URL路由二、request类是如何找到的三、检测域名路由四、总结