前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Laravel 路由匹配的过程都做了些什么呢?

Laravel 路由匹配的过程都做了些什么呢?

作者头像
写PHP的老王
发布2019-09-29 16:04:27
1.3K0
发布2019-09-29 16:04:27
举报
文章被收录于专栏:写PHP的老王写PHP的老王

Laravel 的路由配置有很多,可以设置域名,设置请求协议,设置请求方式,请求路径。那么,Laravel在获取到请求之后,去匹配路由都做了些什么呢?

Laravel 默认路由的验证器有四个,UriValidator,MethodValidator,SchemeValidator,HostValidator分别处理uri的匹配,请求方法的匹配,协议的匹配,域名的匹配。

举几个例子:

1HostValidator验证域名是符合domain的配置

代码语言:javascript
复制
Route::domain('{account}.blog.dev')->function({
    return 'Hello';
});

2UriValidator验证请求的uri是否符合路由配置,MethodValidator验证当前请求方法是否是get方法

代码语言:javascript
复制
Route::get('/home/posts/{id?}',function($id=null){
    return 'get post '.$id;
})

3SchemeValidator验证访问协议,主要用于验证安全路由。只能验证是http,或者https

代码语言:javascript
复制

Route::get('foo', array('https', function(){}));

只有当四个验证器都通过才认为当前请求匹配路由成功。

那这四个验证器都是怎么验证的呢?

请求方法验证

请求方式的验证最简单,就是验证当前请求方式是否是当前路由允许的请求方式。而路由的允许的请求方式在路由实例化的时候就创建好了。

请求协议验证

通过获取当前请求的Request,判断是否是https,与当前路由的配置进行比较

域名验证以及uri的验证

这两种验证本质上都是一样的。通过对路由的配置进行编译分解,获取uri获取域名匹配的正则表达式,然后通过正则表达式进行匹配。如果匹配成功,则验证通过。

这里以UriValidator为例说明

这里的关键是getCompiled返回的这个对象。getCompiled返回的是Symfony\Component\Routing\CompiledRoute这个对象包含了当前路由编译之后的uri匹配正则表达式,域名匹配正则表达式等信息。

CompiledRoute是谁返回的?

在每个路由获取验证器进行验证之前,都会执行compileRoute方法创建CompiledRoute对象。

Illuminate\Routing\RouteCompilercompile方法如下:

可以看出,最终是由Symfony\Component\Routing\RouteCompilercompile返回最终的compileRoute对象。

路由编译都干了些什么?

RouteCompiler::compile输入参数是当前需要匹配的路由。首先判断路由是否有域名配置,如果有域名配置则对域名配置进行正则表达式编译,获取域名的匹配正则表达式,已经匹配表达式中的变量信息。

然后获取路由的uri配置,对配置进行解析获取配置中的匹配正则表达式,变量数组,前缀信息。

域名,路径匹配规则解析之后,根据解析后的数据创建一个CompiledRoute对象,并返回

因此,在路由编译过程中,主要是根据路由配置,解析出匹配的正则表达式,变量数组,前缀信息。并将这些解析之后的数据创建的CompiledRoute对象返回给调用方。这样,调用方就能够直接通过CompiledRoute的属性直接获取到路由解析之后的匹配规则。

匹配规则怎么解析的?

首先通过正则表达式匹配是否由变量配置,例如Route::get('/posts/{id}'),Route::domain('{account}.blog.dev')。如果有变量,则对配置规则进行截取,将配置规则中不包含变量的部分$tokens[] = ['text', $precedingText]; ,对所有变量$token = ['variable', $isSeparator ? $precedingChar : '', $regexp, $varName, false, true]保存解析后的信息。

当配置信息中不包含任何变量,则进入这段代码中第一个if判断里面,将匹配规则保存在token数组中。

区分当前解析是对域名的匹配还是对uri的匹配,如果对uri的匹配,则找出变量中第一个可选参数的位置。

这一步是把路由配置转换成可匹配的规则token。方便后续通过每个token生成匹配正则表达式。

通过解析获取的token数组,保存了所有的匹配规则数组。如果当前匹配规则token是text类型,则在对字符串进行转义处理,返回作为匹配的正则表达式。

如果是变量,则根据是否是可选的(上一步已经找到了第一个可选参数的位置),在正则表达式中添加可选标识。

根据每个token获取每个匹配规则的正则表达式,将所有的正则表达式拼接成一个正则表达式,并加上正则表达式前后缀。这样就获取了一个完整可匹配的正则表达式。

然后将前缀,匹配正则表达式,匹配规则数组tokens,变量数组返回给调用方。供调用方生成CompiledRoute对象。

附上Laravel路由匹配过程调用流程图

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-09-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 写PHP的老王 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 请求方法验证
  • 请求协议验证
  • 域名验证以及uri的验证
  • CompiledRoute是谁返回的?
  • 路由编译都干了些什么?
  • 匹配规则怎么解析的?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档