Cache::get()和Cache::put()易出错主因是未设过期时间或误用array驱动;删缓存需注意前缀;空值缓存须手动处理防穿透;rememberForever()仅redis/memcached真正支持持久化。

Cache::get() 和 Cache::put() 是最常用但容易出错的组合
直接用 Cache::get() 取不到值,八成不是缓存没存,而是忘了存的时候没设过期时间,或者用了默认驱动(如 array)——它只在当前请求生命周期有效,刷新页面就丢。
实操建议:
-
Cache::put('key', $value, 3600)必须显式传入秒数,不能留空;Laravel 10+ 已废弃无过期时间的put()调用 - 检查
CACHE_DRIVER环境变量,本地开发常用file或redis,切勿依赖array做跨请求测试 - 若值是对象或闭包,
redis驱动下会序列化失败,改用json_encode()后存字符串,取回再json_decode()
forget() 删除缓存不生效?先确认 key 是否带前缀
Laravel 默认会给所有缓存 key 加上应用前缀(来自 CACHE_PREFIX 或 APP_NAME),你手动 Cache::forget('users') 其实删的是 users,而实际存的是 myapp_users。
实操建议:
- 用
php artisan tinker运行Cache::getStore()->getPrefix()查当前前缀 - 删缓存优先用
Cache::flush()(清空全部),或改用Cache::pull('key')—— 它取值同时自动删除,避免 get + forget 的竞态 - 批量删可用通配符:Redis 驱动下可调用底层
RedisManager::connection()->keys('myapp_users_*')再逐个del,但注意高并发时慎用keys
缓存穿透问题:查数据库前没校验空值缓存
用户反复请求一个根本不存在的 ID(比如 /user/9999999),每次都会击穿缓存直连 DB。Laravel 自带的 Cache::remember() 不解决这个问题,因为它只对「有值」的结果做缓存。
实操建议:
- 手动处理空结果:
$user = Cache::get('user_123') ?? Cache::remember('user_123', 300, function () use ($id) { return User::find($id) ?: null; });,但注意null不会被缓存,得改成Cache::remember('user_123', 300, fn() => User::find($id) ?: 'NOT_FOUND') - 更稳妥的做法是封装一个辅助函数,比如
cacheNull($key, $ttl, $callback),内部统一用字符串'NULL'占位,取回时判断并返回null - 别把 TTL 设太长——空值缓存建议 60~120 秒,既防穿透,又不至于长期掩盖真实数据上线
使用 rememberForever() 前必须确认驱动支持持久化
Cache::rememberForever('config', fn() => Config::all()) 在 file 或 database 驱动下看似能用,但其实只是把过期时间设为远期(如 Unix 时间戳 32503680000),一旦服务器时间异常或缓存文件被清理,就会失效;而 redis 或 memcached 才真正支持永不过期。
实操建议:
- 永远不要在生产环境用
rememberForever()配file驱动;检查config/cache.php中对应驱动的permanent支持说明 - 若真需要长期缓存,改用
Cache::put('key', $value, now()->addYears(1)),显式控制生命周期,便于后期审计和清理 - 所有
rememberForever()调用点,建议加日志埋点,记录首次写入时间和后续命中情况,避免“以为永存,实则静默丢失”
缓存不是开关,是状态机——存、取、删、失效、穿透、前缀、驱动差异,每个环节都可能断链。最常被忽略的是:你以为删了,其实 key 对不上;你以为存了,其实驱动不持久;你以为空值不缓存,其实框架根本没帮你兜底。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











