opcache缓存绑定php进程,重启即清空属正常设计;持久化需启用opcache.file_cache并确保路径权限正确,业务数据应交由redis等专用缓存处理。

OPcache 本身不支持跨进程持久化,重启 PHP-FPM 就清空是正常行为
OPcache 的缓存数据存储在共享内存中,生命周期绑定于 PHP 进程(如 php-fpm worker 或 Apache 模块)。只要服务重启、进程重载或系统内存回收,缓存就丢失——这不是 bug,是设计使然。所谓“持久化 OPcache”是个常见误解,opcache_reset() 和 opcache_invalidate() 只能操作当前内存实例,无法写入磁盘或跨进程保留。
想减少重启后“冷启动”延迟,得靠 opcache.file_cache 配置
PHP 5.5+ 支持将编译后的 opcode 写入文件缓存目录,供下次启动时快速加载。PHP 7.3 完全支持该功能,但默认关闭。关键点:
-
opcache.file_cache必须设为绝对路径(如/var/tmp/opcache),且 PHP 进程用户(如 www-data)要有读写权限 -
opcache.file_cache_only=0(默认),表示同时启用内存 + 文件缓存;若设为 1,则只用文件缓存(不推荐,性能下降明显) -
opcache.validate_timestamps=1仍需开启,否则文件缓存不会自动校验源码变更 - 首次启动时文件缓存为空,需等请求触发编译后才会生成;后续重启会从该目录加载,跳过重复编译
示例配置片段(php.ini):
opcache.file_cache=/var/tmp/opcache opcache.file_cache_consistency_checks=1 opcache.file_cache_fallback=1
重启后缓存“没生效”,大概率是路径或权限问题
即使开了 opcache.file_cache,也常因以下原因失效:
- 目录不存在或未
chown www-data:www-data /var/tmp/opcache - SELinux 或 AppArmor 拦截了 PHP 对该路径的写入(检查
dmesg | grep avc) - 使用了符号链接路径:OPcache 对
realpath敏感,opcache.file_cache路径必须是真实物理路径,不能是软链目标 - 容器环境未挂载该目录:Docker 中若
/var/tmp/opcache在可写层,容器重建即丢失;应挂载宿主机卷或命名 volume
验证是否启用成功:调用 opcache_get_status(),看返回数组中 file_cache 字段是否为 true,file_cache_path 是否匹配你配置的路径。
真正需要持久化的不是 opcode,而是你的业务数据缓存
如果目标是“重启后用户数据、查询结果、模板渲染结果不丢”,那不该依赖 OPcache——它只管 PHP 脚本编译,不管业务逻辑。你应该:
- 用
APCu存用户级变量(注意:它也不跨进程,但比 OPcache 更适合短生命周期缓存) - 用
Redis或Memcached做真正的跨进程、跨机器持久化缓存(哪怕只是本地 Redis 实例) - 框架层(如 Laravel、Symfony)的缓存驱动要显式配置为 redis 或 file(而非 apcu/opcache),避免误用 opcode 缓存机制存业务数据
OPcache 的角色很窄:加速 require、include、脚本执行。把它当数据库用,迟早踩坑。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











