opcache的核心作用是缓存php脚本编译后的opcode至共享内存,跳过读取、词法分析、语法分析和编译环节,仅保留执行步骤;其失效依赖opcache.validate_timestamps与opcache.revalidate_freq协同控制,开发环境宜设为1和0以实时生效,生产环境应设validate_timestamps=0并配合部署流程手动刷新。

OPcache 的核心作用,是把 PHP 脚本编译后的字节码(Opcode)存进共享内存,让后续请求跳过重复的解析和编译过程。它不缓存输出结果,也不缓存变量或数据库查询——只缓存“代码怎么执行”这一层指令。
脚本从源码到执行,OPcache 插在哪个环节?
PHP 执行一个脚本要经历四步:读取文件 → 词法分析(拆成 Token)→ 语法分析(建 AST)→ 编译成 Opcode → 执行。OPcache 拦截在“编译完成之后、执行之前”这个节点,把生成好的 Opcode 数组连同元数据(如文件路径、修改时间、配置哈希)一起写入共享内存。下一次请求同一脚本时,只要缓存有效,就直接加载 Opcode 执行,省掉前三个耗 CPU 和磁盘 I/O 的步骤。
缓存什么时候失效?关键看两个开关
OPcache 判断脚本是否“已更新”,依赖以下两个配置协同工作:
- opcache.validate_timestamps:是否开启时间戳校验。设为 1 表示启用,0 表示完全关闭(生产环境推荐关)
- opcache.revalidate_freq:校验间隔(单位秒)。仅当 validate_timestamps=1 时生效;设为 0 表示每次请求都检查文件修改时间
举例:若 validate_timestamps=1 且 revalidate_freq=60,那么 OPcache 每 60 秒检查一次文件是否被改过;期间即使你刚部署了新代码,旧缓存仍会继续用满这 60 秒。这就是为什么改完代码页面没变——不是没部署成功,而是缓存还没“发现”变化。
失效后不是立刻删,而是标记为“Wasted”
OPcache 不会在检测到文件变更时马上释放内存。它只是把对应缓存条目标记为“已失效(Wasted)”,继续占用空间。只有当 Wasted 内存占比超过阈值(由内部机制控制),或者手动调用 opcache_reset()、重启 PHP-FPM 进程时,才会真正清空并重建整个缓存区。
- 这种设计减少锁竞争和内存碎片,适合高并发场景
- 但也会导致内存使用率缓慢上升,尤其在频繁部署的环境中
- 可通过
opcache_get_status()['memory_usage']['wasted_percentage']查看当前浪费比例
开发与生产,该用哪种失效策略?
开发环境建议开启实时校验:
- opcache.validate_timestamps = 1
- opcache.revalidate_freq = 0
这样改完保存就能立刻看到效果,无需重启服务。
生产环境则应关闭自动校验:
- opcache.validate_timestamps = 0
- 靠部署流程触发
opcache_reset()或重启 PHP-FPM 来强制刷新
避免每秒数百次 stat 系统调用拖慢响应,也防止因 NFS 挂载、容器文件系统等导致的时间戳读取不准问题。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











