
laravel 中使用 route model binding 会提前加载模型,导致缓存逻辑被绕过;正确做法是禁用自动绑定,改用原始 id 参数手动查询并缓存。
laravel 中使用 route model binding 会提前加载模型,导致缓存逻辑被绕过;正确做法是禁用自动绑定,改用原始 id 参数手动查询并缓存。
在 Laravel 8 中,Redis 缓存未生效的典型原因之一是无意中触发了隐式路由模型绑定(Implicit Route Model Binding)。如您代码所示,控制器方法签名 show(Application $application) 会让 Laravel 在执行 Cache::remember() 之前,就通过 $application 参数自动调用 Application::find($id) 并实例化模型——这意味着数据库查询已在缓存逻辑外完成,后续 Cache::remember() 实际缓存的是已加载的对象(或空操作),完全失去加速意义。
✅ 正确实现:禁用模型绑定,显式传入 ID
将控制器方法改为接收原始 ID,并在闭包内执行查询:
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$application = Cache::store('redis')->remember(
"application:{$id}",
now()->addMinutes(30),
function () use ($id) {
return Application::with([
'payday', 'response', 'apiLinks'
])->find($id); // 注意:find() 已返回模型实例,无需再链式调用 ->first()
}
);
if (! $application) {
return response()->json(['error' => 'Application not found'], 404);
}
return response()->json(['application' => $application], 200);
}
? 关键修正点说明:
- 方法参数从 Application $application 改为 $id,彻底避免隐式绑定;
- Cache::remember() 的键名使用字符串 "application:{$id}",确保唯一性与可预测性;
- Application::find($id) 本身即返回单个模型(或 null),无需额外 ->first();
- 建议添加 null 检查,提升 API 健壮性。
⚠️ 注意事项
-
路由定义需同步调整:确保 routes/api.php 中对应路由不依赖类型提示绑定,例如:
Redis Skill - 高性能缓存管理下载Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
Route::get('/applications/{id}', [ApplicationController::class, 'show']);而非 Route::get('/applications/{application}', ...)(后者会触发绑定)。
缓存键设计建议:若关联关系数据可能变更,可在键中加入版本号或哈希(如 md5(serialize(['includes' => ['payday','response']]))),便于主动刷新缓存。
-
验证 Redis 是否真正生效:可通过 php artisan tinker 手动测试:
>>> Cache::store('redis')->put('test:key', 'hello', 60); >>> Cache::store('redis')->get('test:key') => "hello"
通过移除隐式绑定、显式控制查询时机,Redis 缓存才能真正拦截重复的重型查询(如 1000 万行关联加载),将响应时间从秒级降至毫秒级。这是 Laravel 缓存实践中的关键认知分水岭。










