当opcache.validate_timestamps=0时,OPcache完全禁用时间戳校验,不检查文件变更,新代码不生效;必须手动调用opcache_invalidate()或opcache_reset()刷新缓存,并用opcache_is_script_cached()等函数验证。

当 opcache.validate_timestamps=0 时,OPcache 完全禁用文件时间戳校验,意味着它**不会主动检查 PHP 文件是否被修改**。此时即使你替换了代码文件,OPcache 仍会持续使用内存中缓存的旧字节码,导致新代码完全不生效。
必须手动触发缓存刷新
关闭时间戳验证后,OPcache 不再“自动感知”变更,只能靠显式调用来清理缓存:
-
刷新单个文件:用
opcache_invalidate($file, true),适合发布脚本能精确识别变更文件的场景。注意路径必须是绝对路径,且文件需已加载进 OPcache(首次访问过或被opcache_compile_file()预热过)。 -
清空全部缓存:直接调用
opcache_reset()。它会清空所有已编译脚本,下次请求重新加载并编译——简单粗暴,适合中小型项目或部署后一键重置。 -
避免只改配置不重启:仅把
validate_timestamps改回 1 并不生效,该配置在 PHP 启动时读取;必须重启 PHP-FPM 或 Apache 才能加载新值。但重启不是推荐解法,它会造成请求中断,且掩盖了“应主动管理缓存”的设计问题。
确认刷新是否成功
别凭感觉判断,用内置函数验证:
- 调用
opcache_is_script_cached($file)查看目标文件是否还在缓存中; - 执行
opcache_get_status()['scripts']查看当前缓存的脚本列表及最后修改时间(注意:这个时间是缓存加载时记录的,不是磁盘文件时间); - 在新代码里加一行
error_log('v2.1 loaded');,然后查 PHP 错误日志——没输出就说明缓存没刷干净或没加载到新版本。
顺便检查 realpath 缓存
即使 OPcache 刷干净了,realpath() 函数也有自己的路径缓存(尤其在大量 include/require 的项目中),它不受 OPcache 控制。可调用 clearstatcache(true) 清除文件状态和 realpath 缓存,或在部署脚本末尾加上:
立即学习“PHP免费学习笔记(深入)”;
clearstatcache(true); opcache_reset();
生产环境建议的发布流程
关闭 validate_timestamps 本身是为性能让步,但必须配套自动化刷新机制:
- CI/CD 脚本在文件同步完成后,自动调用
opcache_reset()(通过 CLI PHP 执行); - 若用容器部署,可在启动脚本里加
php -r "opcache_reset();"; - 禁止依赖浏览器刷新或等待“过一会儿”,因为缓存不会自行更新;
- 监控项可加入
opcache_get_status()['opcache_enabled']和['memory_usage']['used_memory'],确保 OPcache 真正启用且有内容。



















