Laravel PUT路由的id参数未传入控制器activate方法是什么原因?
问题原因
你遇到的参数无法正确注入的核心问题是Laravel隐式模型绑定的参数名不匹配,同时存在路由顺序的潜在风险:
- 路由定义中路径参数名为
{id},但控制器方法里类型提示的模型变量名为$ad,Laravel隐式模型绑定要求路由参数名和控制器方法的类型提示变量名完全一致才能自动查询注入模型实例,二者不匹配的情况下,Laravel只会注入一个未初始化的空Ad模型对象,所以$ad->id为null。 - 你当前把自定义的
activate路由放在了ads资源路由之后,虽然当前版本默认路由参数不会匹配斜杠不会触发冲突,但更规范的写法是将自定义资源路由放在资源路由声明之前,避免后续路由规则调整后出现匹配优先级问题。
解决方案
方案一(推荐):修改路由参数名和控制器变量匹配
将routes/api.php中的路由定义修改为:
Route::middleware('auth:sanctum')->group( function () { Route::post('logout', [AuthController::class, 'logout']); // 自定义路由放在资源路由前 Route::put('ads/{ad}/activate', [AdController::class, 'activate']); Route::resource('ads', AdController::class); });
修改后路由参数{ad}和控制器方法的$ad变量名匹配,Laravel会自动用路径中传入的数值作为主键查询Ad模型,注入正确的实例到控制器中。
方案二:修改控制器参数名和路由匹配
如果不想改路由,可以将控制器方法签名调整为:
public function activate(Request $request, Ad $id)
即可触发隐式绑定,但变量名$id语义性较差,不推荐使用。
方案三:显式指定路由绑定
如果有特殊业务需求不想修改参数名,可以在路由定义时显式指定绑定的模型:
Route::put('ads/{id}/activate', [AdController::class, 'activate'])->scopeBindings(); // 或者在RouteServiceProvider中全局指定参数绑定: // Route::model('id', \App\Models\Ad::class);
内容的提问来源于stack exchange,提问作者Petro Gromovo
相关产品推荐
相关产品推荐

