php缓存实操避坑指南:文件缓存须加lock_ex防并发损坏,apcu需校验扩展启用与false值歧义,redis连接要设读超时并区分空字符串与false,opcache改配置必须重启进程,缓存失效需关联清理多键。

file_get_contents 读缓存但没检查返回值是否为 false,结果页面直接白屏。
文件缓存怎么写才不翻车
文件缓存适合本地调试、小流量后台或配置项缓存,但极易因并发写入或路径权限崩掉。
-
cache_set()必须加file_put_contents($file, serialize($data), LOCK_EX)——漏掉LOCK_EX多进程写同一文件时大概率数据损坏 - 判断过期不能只靠
filemtime(),要先clearstatcache(true, $file),否则 PHP 可能缓存文件元信息导致误判 - 缓存文件名别用原始参数拼接,必须
md5($key)或spl_object_hash(),否则路径里带../会触发目录穿越 - 不要把缓存目录放在 Web 可访问路径下(如
./public/cache/),否则别人直接请求/cache/xxx.cache就能下载反序列化后的内容
APCu 缓存为什么 fetch 总是 false
apcu_fetch() 返回 false 不一定代表没命中:它也可能是你存的时候值本身就是 false,或者 APCu 模块根本没启用。
- 先执行
extension_loaded('apcu')和ini_get('apc.enabled'),确认扩展已加载且开启;CLI 模式下还要看apc.enable_cli是否为 1 - 存值时避免直接
apcu_store('key', false),改用包装结构:apcu_store('key', ['value' => false, 'ts' => time()]) - 共享内存大小不够会静默淘汰旧条目,查
apcu_cache_info()['mem_size'] / apcu_cache_info()['memory_usage']看是否接近 100% -
apcu_clear_cache('user')在生产环境慎用——它清的是整个实例,不是单个 key
Redis 缓存连接失败的三个高频原因
用 phpredis 扩展连 Redis,90% 的报错不是密码或端口错,而是底层行为差异没对齐。
- 连接后没调
$redis->setOption(Redis::OPT_READ_TIMEOUT, 0.5),默认阻塞 1 秒,高并发下积压大量等待连接 - 用
setex()存字符串没问题,但存数组/对象必须自己json_encode(),Redis 不识别 PHP 序列化格式;取回后也得json_decode($val, true) -
get()返回空字符串''和返回false含义不同:前者是 key 存在但值为空,后者才是 key 不存在——别用empty()统一判断 - Redis 默认最大连接数 10000,但 PHP-FPM 子进程多时容易打满,建议在连接池外加
try/catch (RedisException $e)并降级到文件缓存
OPcache 配置改了为啥没生效
OPcache 是唯一一个“改完 php.ini 就得重启 PHP 进程”的缓存,光 reload nginx/apache 不管用。
- 验证是否启用:
var_dump(opcache_get_status()['opcache_enabled']),返回true才算成功 -
opcache.revalidate_freq=2表示每 2 秒检查一次文件修改时间,设为 0 就变成每次请求都校验,等于关缓存 - 如果用了 Docker,确保宿主机代码挂载进容器时没用
:ro只读模式,否则 OPcache 无法监听文件变化 - CLI 脚本默认不走 OPcache,除非显式开启
opcache.enable_cli=1,否则单元测试里永远测不到编译缓存效果
product_123、category_electronics、homepage_promo 三条缓存——这个逻辑一旦漏掉,前端就永远显示旧价。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











