Laravel 之路由匹配

前言

在阅读这篇文章之前,我希望你阅读了老司机带你实现 Laravel 之管道老司机带你实现 Laravel 路由注册功能,还有老司机带你深入理解 Laravel 中间件(全局中间件),它们是阅读这篇文章的基础。

流程分析

废话不多说,咱们直接分析Laravel代码,上次我们分析Laravel全局的全局中间件,代码如下所示:

picture alt

全局中间件运行完之后,会调用dispatchToRouter方法返回的回调方法,我们看一下这个方法:

picture alt

当前类Illuminate\Foundation\Http\Kernel$router属性是Illuminate\Routing\Router类的对象,下面我们看
Illuminate\Routing\Router类的dispatch方法,如下:

picture alt

继续调用dispatchToRoute方法,如下:

picture alt

我们今天的重点是findRoute方法,也就是寻找路由。

picture alt

Router类的routes属性是一个Illuminate\Routing\RouteCollection类的实例,我们注册的所有路由都存储在这个类的实例中,下面我们进入到的Illuminate\Routing\RouteCollection类的match方法中,如下:

picture alt

在下面的讲解中,我们以get请求为例,上面首先调用当前对象的get方法,这个方法返回注册的所有的get请求路由,接下来调用matchAgainstRoutes方法,这个方法有必要说一下:

picture alt

在讲上面的代码之前,我要提到Laravel的回退路由,这是啥呢?Laravel官方的文档:Fallback Routes,我先截图如下:

picture alt

关于回退路由的解释我上面说过了。回到matchAgainstRoutes方法中,这个方法分为2部分,第一部分把所有的get路由分为2个容器,第一个容器只包含回退路由,第二个容器包含除去回退路由的所有get路由。第二部分把上面的2个容器合并,注意了此时的回退路由在所有get路由的的最后面。合并完之后遍历容器中的每一个路由,找到第一个符合规则的路由,上面的first方法的每一个参数都是我们注册的路由对象,Laravel中的每一个路由对象都是Illuminate\Routing\Route类的实例,下面我们进入到这个方法中:

picture alt

首先调用compileRoute方法,该方法如下:

picture alt

这个方法会返回一个\Symfony\Component\Routing\CompiledRoute类的对象,我们先来看一下Illuminate\Routing\RouteCompile类的compile方法:

picture alt

在上面的代码中,Laravel本身做的事情非常少,提取可选参数,并把可选参数,路由参数定义等信息传递给\Symfony\Component\Routing\CompiledRoute类,剩下的事情就不管了,由于Laravel这里调用的是第三方组件Symfony的代码,所以我们在这里暂不分析,你只需要知道这些就行(以后再给大家仔细分析),好了,经过上面的这些流程,我们返回到Illuminate\Routing\Route类的matches方法中,执行如下代码:

picture alt

方法getValidators返回了一个由Illuminate\Routing\Matching\ValidatorInterface接口实例组成的实例数组:

picture alt

我们任意分析一个,就以为例Illuminate\Routing\Matching\MethodValidator类为例:
picture alt

它的matches方法检测当前请求的方法是不是合法的请求方法,回到matches方法中,如果所有的ValidatorInterface返回为true,matches方法才会返回true,否则为false。

其它的ValidatorInterface都是一样的,不再详述。

总结

经过上面简要的分析,对于你弄懂Laravel的路由匹配已经足够了,祝您学习愉快。

本作品采用《CC 协议》,转载必须注明作者和本文链接
微信:okayGoHome
Dennis_Ritchie
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 2
wanghan

谢谢巨佬

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!