Laravel带locale前缀路由控制器接收$id返回语言值问题咨询
问题原因
- Laravel路由参数按定义顺序依次注入控制器方法,你最外层路由定义了前缀参数
{locale},该路由组下所有路由的第一个参数都是locale,第二个才是资源路由生成的partner参数。 - 你使用隐式模型注入时参数名与路由参数名不匹配:
Route::resource('partner', ...)生成的路由参数名为{partner},但你控制器方法里的注入参数名为$partnerForm,导致隐式注入未生效。 - 控制器
show方法没有先接收$locale参数,Laravel就将第一个路由参数en按顺序赋值给了你定义的$id,所以打印$id得到的是语言标识而非资源ID。
解决方案
方案1:调整控制器参数顺序,匹配路由参数名
直接调整show方法的参数顺序和名称,让路由参数正确匹配,同时隐式注入会自动帮你查询对应模型,无需手动写DB查询:
public function show(string $locale, PartnerForm $partner) { // $partner 就是ID对应的PartnerForm模型实例,直接使用即可 return view('admin.partner-details', compact('partner')); }
同时建议生成路由时显式传递所有参数,避免潜在异常:
<a href="{{ route('admin.partner.show', ['locale' => app()->getLocale(), 'partner' => $partner->id]) }}" class="text-indigo-600 hover:text-indigo-900">Edit</a>
方案2:中间件剥离locale参数(更推荐)
如果不想每个控制器方法都重复接收$locale参数,可以在你的setlocale中间件中加入一行代码,移除路由参数中的locale,后续控制器就不需要再接收该参数:
// 在setlocale中间件处理逻辑中加入以下代码 $request->route()->forgetParameter('locale');
之后控制器show方法可以直接写成:
public function show(PartnerForm $partner) { return view('admin.partner-details', compact('partner')); }
调整后路由生成也可以直接传递资源ID即可,和你之前的写法保持一致。
内容的提问来源于stack exchange,提问作者Khairin Chan
相关产品推荐
相关产品推荐

