Laravel主数据变更时如何更新永久缓存数据?
解决Laravel永久缓存(Cache::rememberForever)的数据更新问题
当你用Cache::rememberForever实现永久缓存时,核心思路是在主数据发生变更时,主动清除对应缓存键——因为永久缓存不会自动过期,只有删除后,下次请求才会重新执行闭包生成新的缓存数据。下面是几个生产环境常用的最优方案:
方案1:数据变更时手动删除缓存键
这是最直接、易维护的方案,适合业务逻辑简单的场景。在处理数据更新/删除的方法中,完成数据库操作后,直接调用Cache::forget()清除对应缓存。
示例代码:
缓存读取(控制器index/show方法)
public function show(User $user) { // 用用户ID作为缓存键的一部分,保证唯一性 $userData = Cache::rememberForever("user_detail_{$user->id}", function () use ($user) { // 这里返回需要缓存的最终数据,比如关联了头像、角色的用户信息 return $user->load(['avatar', 'roles']); }); return view('users.show', compact('userData')); }
数据更新时清除缓存(控制器update方法)
public function update(Request $request, User $user) { // 验证并更新数据库数据 $user->fill($request->validated())->save(); // 清除对应永久缓存 Cache::forget("user_detail_{$user->id}"); return redirect()->route('users.show', $user); }
方案2:利用模型事件自动处理缓存
如果多个地方都可能修改用户数据(比如后台、API、队列任务),手动删缓存容易遗漏。这时可以用Laravel模型事件,在数据变更时自动触发缓存清除逻辑,实现全局统一处理。
示例代码(User模型):
class User extends Model { protected static function booted() { // 当用户数据被创建、更新时触发saved事件 static::saved(function (User $user) { Cache::forget("user_detail_{$user->id}"); // 如果有其他关联缓存(比如用户帖子列表),也一起删除 Cache::forget("user_posts_{$user->id}"); }); // 用户被删除时触发deleted事件 static::deleted(function (User $user) { Cache::forget("user_detail_{$user->id}"); }); } }
这样不管通过什么方式修改用户数据,只要模型触发saved/deleted事件,缓存就会自动清除,无需在每个业务方法中重复写清除逻辑。
方案3:缓存标签批量管理(多缓存键场景)
如果一个用户对应多个缓存键(比如个人信息、帖子列表、收藏列表),一个个删除太繁琐,可以用Redis支持的缓存标签,给同一用户的所有缓存打上标签,数据变更时直接清空整个标签下的缓存。
示例代码:
带标签的缓存读取
// 用户详情缓存 $userData = Cache::tags(["user_{$user->id}"])->rememberForever('user_detail', function () use ($user) { return $user->load(['avatar', 'roles']); }); // 用户帖子列表缓存 $userPosts = Cache::tags(["user_{$user->id}"])->rememberForever('user_posts', function () use ($user) { return $user->posts()->latest()->take(10)->get(); });
数据变更时清空标签下所有缓存
public function update(Request $request, User $user) { $user->fill($request->validated())->save(); // 清空该用户标签下的所有缓存 Cache::tags(["user_{$user->id}"])->flush(); return redirect()->route('users.show', $user); }
注意事项
- 缓存键命名要唯一:建议带上模型ID、业务标识(如
user_detail_123),避免不同缓存之间冲突。 - 缓存轻量化:尽量缓存处理后的最终数据,不要缓存整个模型实例,减少Redis内存占用。
- 复杂列表缓存:如果是用户列表(index方法)的永久缓存,缓存键要考虑筛选条件(如
user_list_active、user_list_admin),更新时要对应清除所有相关的列表缓存键。
内容的提问来源于stack exchange,提问作者Rasoul Karimi
相关产品推荐
相关产品推荐

