Laravel 5如何避免路由前缀作为子路由控制器函数首个参数传递?
解决路由前缀参数被传递给子路由控制器的问题
这个问题我之前也踩过坑,本质是Laravel会按路由参数的定义顺序自动注入到控制器方法中——你的{locale}作为前缀参数排在第一位,自然会被传给控制器的第一个参数,导致原本该接收车辆ID的$id拿到了locale值。不用在每个控制器方法里都硬加$locale参数,有个很简便的解决办法:
方法:用中间件处理Locale并移除路由参数
1. 创建Locale处理中间件
先生成一个专门处理locale的中间件,用来设置应用语言,同时把locale参数从路由中移除,这样就不会传递给控制器了:
php artisan make:middleware SetLocale
打开生成的app/Http/Middleware/SetLocale.php,修改handle方法:
public function handle(Request $request, Closure $next) { // 获取路由中的locale参数 $locale = $request->route('locale'); // 验证locale是否是你支持的语言(避免非法值) if (in_array($locale, ['en', 'fr', 'it'])) { app()->setLocale($locale); } // 关键:移除locale参数,不让它传递给控制器 $request->route()->forgetParameter('locale'); return $next($request); }
2. 注册中间件
打开app/Http/Kernel.php,在$routeMiddleware数组里注册这个中间件:
protected $routeMiddleware = [ // ... 其他中间件 'setlocale' => \App\Http\Middleware\SetLocale::class, ];
3. 修改路由组定义
把你的路由前缀组和这个中间件绑定,这样所有子路由都会经过这个中间件处理:
Route::prefix('{locale}') ->middleware('setlocale') ->where('locale', 'en|fr|it') // 可选:约束locale的合法值 ->group(function () { Route::get('/cars/{id}', [CarController::class, 'getCar']); // 其他子路由... });
4. 调整控制器方法
现在你可以把控制器里临时加的$locale参数删掉,恢复原本的方法定义:
public function getCar($id) { // 这里的$id会正确接收车辆ID,locale已经被中间件处理好了 $car = Car::findOrFail($id); // ... 其他逻辑 }
原理说明
Laravel的路由参数会按定义顺序自动注入到控制器方法中,当我们用$request->route()->forgetParameter('locale')移除这个参数后,路由传递给控制器的参数列表里就只剩下后续的{id}了,所以$id就能正确拿到对应的值,同时locale也被中间件处理并设置到应用中,一举两得。
内容的提问来源于stack exchange,提问作者stevetronix
相关产品推荐
相关产品推荐

