Laravel控制器未从路由获取正确参数,进入错误方法
Laravel路由匹配异常问题解析
问题核心
你定义了如下路由:
Route::match(['get', 'post'], '/{class}/{function}/', [OldBackendController::class, 'apiV1']);
但发起POST /api/v2_1/wishlist/archive请求时,却匹配到了该路由,且控制器中$class变量的值为api/v2_1/wishlist,同时$request->segments()能正常获取到4个分段:
Array ( [0] => api [1] => v2_1 [2] => wishlist [3] => archive )
原因分析
这是因为Laravel路由的参数默认是贪婪匹配模式:{class}这类无约束的参数会匹配任意字符(包括斜杠/)。当路由定义为两级参数/{class}/{function}/时,请求的四级路径会被拆解为:
{function}匹配最后一个分段archive- 剩下的
api/v2_1/wishlist全部被{class}捕获
所以即使请求有4个分段,依然会匹配到这个两级参数的路由。
解决方案
1. 给路由参数添加正则约束
通过where方法限制参数不能包含斜杠,确保每个参数只能匹配单个路径分段:
Route::match(['get', 'post'], '/{class}/{function}/', [OldBackendController::class, 'apiV1']) ->where([ 'class' => '[^/]+', 'function' => '[^/]+' ]);
添加约束后,{class}和{function}只能匹配不含斜杠的分段,四级路径就无法匹配该路由了。
2. 调整路由定义顺序
Laravel路由是自上而下匹配的,如果你的/api/v2_1/...有对应的专属路由,要把它放在这个通用路由的前面。这样请求会优先匹配到具体路由,而不是被这个通用路由拦截。
内容的提问来源于stack exchange,提问作者Giacomo M
相关产品推荐
相关产品推荐

