文件缓存需保障原子性、过期判断与并发安全,应使用file_put_contents($path, $data, lock_ex)加锁,缓存名用md5($key.$version)实现版本控制,读前须校验file_exists()和filemtime(),路径应避免硬编码/tmp/而改用项目内runtime/cache/。

PHP 文件缓存怎么写才不踩坑
文件缓存不是“写个 file_put_contents() 就完事”,关键在原子性、过期判断和并发安全。直接手写容易出现缓存脏读或覆盖丢失。
- 用
file_put_contents($path, $data, LOCK_EX)强制加锁,避免多请求同时写入导致数据截断 - 缓存文件名别硬编码时间戳,改用
md5($key . $version),版本号一变旧缓存自动失效 - 读缓存前必须检查
file_exists()和filemtime(),不能只靠文件存在就认为有效 - 不要把缓存路径写死成
/tmp/—— 某些共享主机限制该目录写权限,建议用项目内runtime/cache/
Memcached 连不上?先看这三件事
连不上 Memcached 多数不是配置错,而是环境链路没通。PHP 扩展装了 ≠ 服务在跑 ≠ 网络可达。
- 执行
telnet 127.0.0.1 11211,不通就说明服务没启或防火墙拦了,别急着查new Memcached() -
php -m | grep memcached确认扩展已加载,注意区分memcache(老)和memcached(新,推荐) - 连接后立刻调用
$mc->getVersion(),返回 false 说明认证失败或服务器拒绝响应,不是超时
文件缓存 vs Memcached:什么场景该选谁
不是“越快越好”,而是“哪条路更稳、更省事”。小项目、低并发、无运维支持时,文件缓存反而是更可靠的选择。
- 单机部署、QPS ls -l runtime/cache/ 看
- 多台 Web 服务器、需共享会话或实时更新缓存(如商品库存)、缓存键动态高频变化 → 必须用 Memcached:文件缓存跨机器不同步,且
filemtime()在 NFS 上不准 - 缓存值含 PHP 对象(如
DateTime)→ 文件缓存用serialize()+unserialize()风险高,Memcached 默认只存字符串,更安全
缓存失效逻辑最容易漏掉的点
缓存写对了,但删不干净,是比不缓存还糟的情况——用户看到的永远是旧数据。
立即学习“PHP免费学习笔记(深入)”;
- 删缓存不是“删一个键”,比如文章详情页缓存键是
post_123,关联的列表页缓存posts_home也得同步删 - 用文件缓存时,
unlink()前务必确认文件属于当前应用(检查realpath()和is_file()),否则可能误删系统文件 - Memcached 的
delete()不保证立即生效(LRU 清理有延迟),高频更新场景建议用带版本号的键,比如post_123_v2,而不是反复删改同一键
缓存真正难的从来不是“怎么存”,而是“什么时候删”和“删得干不干净”。尤其是涉及多级缓存、异步任务或定时脚本时,一条失效路径漏掉,就可能让线上数据卡在上一秒。











