🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
#### 路由变量 上一篇我们系统学习了下路由的执行和检查流程,下面就来细化每一个部分的学习,本篇就主要来深入学习下路由变量的定义和使用。 一个应用的路由规则应该在设计之初就规范好,并尽量避免在项目过程中更改路由。 尤其是做API接口开发的时候,URL地址或者路由的变更将会是一个噩梦的开始。 定义路由变量其实就相当于在规划你的URL地址,路由规则应该是全局唯一的,为了确保没有任何的冲突,做好统一的URL规划至关重要。 #### 普通变量定义 路由规则一般由静态地址和动态变量组成,可以包含必须变量和可选变量。 路由规则中的变量有两种定义方式,比较常见的就是下面的写法: ~~~ Route::get('hello/:name','index/index/hello'); ~~~ 获取路由变量的值可以使用当前Request请求对象直接获取,例如: ~~~ http://tp5.com/hello/thinkphp ~~~ 就可以使用下面的两种方法获取变量值: ~~~ // 获取路由变量 request()->route('name'); // 获取当前请求变量 request()->param('name'); ~~~ 为了更简单的获取,通常我们可以使用参数绑定功能直接把路由变量传入控制器的方法,例如: ~~~ <?php namespace app\index\controller; class Index { public function hello($name) { return 'Hello,' . $name . '!'; } } ~~~ hello方法的name参数的值就是路由变量name的值。 默认情况下,路由规则并不是完整匹配,所以下面的URL地址都是可以匹配的: ~~~ http://tp5.com/hello/thinkphp http://tp5.com/hello/thinkphp/city/shanghai ~~~ 路由规则之外的变量解析方式一般是`key1/value1/key2/value2`解析为`key1=value1,key2=value2`,也就是说 ~~~ http://tp5.com/hello/thinkphp/city/shanghai ~~~ 除了会解析路由变量name之外,还会解析另外一个city变量,分别是: ~~~ 'name' => 'thinkphp', 'city' => 'shanghai' ~~~ 在pathinfo的URL地址中解析的变量我们都称为路由变量,路由变量的获取方式可以是Request请求对象的route或者param方法,但不能使用get方法获取。 如果访问地址是 ~~~ http://tp5.com/hello/thinkphp?city=shanghai ~~~ 那么city变量就是一个get变量,而不是路由变量,虽然值是相同但类型完全不同。 在某些特殊的情况下,额外路由变量(这里指的是路由规则中定义变量之外的URL变量)的解析规则有所区别,当 ~~~ 'url_param_type' => 1 ~~~ 的时候,表示URL变量的解析方式为按顺序解析,这个时候如果访问 ~~~ http://tp5.com/hello/thinkphp/city/shanghai ~~~ 得到的变量结果就完全不同了,如果输出param方法的结果其实是: ~~~ 'name' => 'thinkphp', 0 => 'city', 1 => 'shanghai', ~~~ #### 完整匹配 如果希望仅仅匹配 ~~~ http://tp5.com/hello/thinkphp ~~~ 而不能访问这种地址 ~~~ http://tp5.com/hello/thinkphp/city/shanghai ~~~ 就可以使用完整匹配功能,路由定义规则改为: ~~~ Route::get('hello/:name$','index/index/hello'); ~~~ 路由规则最后用`$`结尾就表示该路由规则是完整匹配的。 (有部分情况下注册的路由规则是自动完整匹配的,比如说资源路由,我们后面会讲到。) 或者使用路由参数 ~~~ Route::get('hello/:name','index/index/hello',['complete_match'=>true]); ~~~ 两种方式的作用是相同的(实际上使用$结尾的路由定义最终也会解析成`complete_match`参数的方式)。 > 【5.1须知】 可以使用下面的方法定义局部完整匹配 ~~~ Route::get('hello/:name','index/index/hello')->completeMatch(); ~~~ 如果需要全局的路由规则定义都是完整匹配的话,可以直接修改应用的配置参数: ~~~ 'route_complete_match' => true ~~~ 当开启全局完整匹配后,个别路由规则也支持单独关闭完整匹配,使用下面的方式即可: ~~~ Route::get('hello/:name','index/index/hello',['complete_match'=>false]); ~~~ #### 变量规则 默认情况下,路由变量会匹配所有的字符,但很多时候,我们需要约束变量的规则进行路由匹配: ~~~ Route::get('hello/:name/[:city]','index/index/hello',[],[ 'name' => '[A-Za-z0-9]+' , 'city' => '[A-Za-z]+' ]); ~~~ 分别对name和city变量定义了变量规则(采用正则表达式)。 > 【5.1须知】 可以使用下面的方法定义变量规则 ~~~ Route::get('hello/:name/[:city]','index/index/hello') ->pattern(['name'=> '[A-Za-z0-9]+' , 'city' => '[A-Za-z]+' ]); ~~~ 或者多次调用 ~~~ Route::get('hello/:name/[:city]','index/index/hello') ->pattern('name','[A-Za-z0-9]+') ->pattern('city','[A-Za-z]+'); ~~~ 下面的URL地址会正确匹配 ~~~ http://tp5.com/hello/thinkphp2015 http://tp5.com/hello/2015/beijing ~~~ 下面的URL地址则无效 ~~~ http://tp5.com/hello/think_php http://tp5.com/hello/thinkphp/2015 ~~~ 也可以统一对路由变量进行全局规则定义: ~~~ Route::pattern([ 'name' => '[A-Za-z0-9]+' , 'city' => '[A-Za-z]+' ]); ~~~ 这样就无需在注册路由规则的时候定义变量规则了,如果同时使用pattern方法和路由定义的时候定义变量规则,那么路由规则定义优先。 ~~~ Route::pattern([ 'name' => '[A-Za-z0-9]+' , 'city' => '[A-Za-z]+' ]); Route::get('hello/:name/[:city]','index/index/hello',[],[ 'name' => '\w+' , 'city' => '[A-Za-z]+' ]); ~~~ 实际匹配`hello/:name/:city`的时候name变量的规则为` \w+`。 注意和pattern方法调用顺序无关。 * * * * * https://www.kancloud.cn/thinkphp/route-master/223111