Laravel的路由系统支持链式调用语法,让开发者可以在一行代码中完成路由的定义、参数约束、中间件绑定等操作,其中where方法是路由参数约束的核心方法,用来限制路由参数的匹配规则,只有符合正则规则的参数才能命中对应路由。
where方法基本语法
where方法属于路由定义链式调用的一部分,通常跟在Route::get()、Route::post()等路由方法之后,基本语法格式如下:
<?php
// 基础语法:where(参数名, 正则规则)
Route::get('/user/{id}', function ($id) {
return '用户ID:' . $id;
})->where('id', '[0-9]+');
上面的代码中,{id}是路由参数,where('id', '[0-9]+')表示id参数只能由数字组成,如果访问/user/abc这样的地址,就不会匹配到这个路由。
多参数约束用法
如果需要同时约束多个路由参数,可以直接在where方法中传入关联数组,键是参数名,值是对应的正则规则:
<?php
Route::get('/article/{category}/{id}', function ($category, $id) {
return '分类:' . $category . ',文章ID:' . $id;
})->where([
'category' => '[a-zA-Z]+',
'id' => '[0-9]+'
]);
这个路由要求category参数只能是字母,id参数只能是数字,比如/article/php/123可以正常匹配,/article/123/php则无法匹配。
闭包约束用法
除了传入正则字符串,where方法也支持传入闭包函数,对参数进行更灵活的校验,闭包接收参数值,返回布尔值表示是否匹配:
<?php
Route::get('/order/{order_no}', function ($order_no) {
return '订单号:' . $order_no;
})->where('order_no', function ($value) {
// 订单号规则:以ORD开头,后面跟8位数字
return preg_match('/^ORDd{8}$/', $value) === 1;
});
全局约束与where方法的区别
Laravel还支持在RouteServiceProvider中定义全局参数约束,让所有包含对应参数的路由都自动应用约束,而where方法是针对单个路由的约束:
<?php
// RouteServiceProvider中的boot方法
public function boot()
{
Route::pattern('id', '[0-9]+');
parent::boot();
}
定义全局约束后,所有路由中的{id}参数都会默认应用数字约束,不需要再单独调用where方法。如果某个路由需要特殊的id约束,可以再用where方法覆盖全局规则。
注意事项
- where方法的正则规则不需要写定界符和修饰符,Laravel会自动处理正则匹配逻辑。
- 如果路由参数没有用where方法约束,默认会匹配除了
/之外的任意字符。 - 链式调用中where方法可以多次调用,效果和传入数组一致:
<?php
Route::get('/test/{a}/{b}', function ($a, $b) {
return $a . '-' . $b;
})->where('a', '[0-9]+')->where('b', '[a-z]+');