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
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。