根本原因是多层缓存叠加:opcache(最常见)、cdn/反向代理、浏览器缓存、框架缓存(如laravel的config/view)及redis等数据缓存共同作用;需逐层排查并针对性清除,仅刷新浏览器或修改php头无效。

PHP网站部署后出现“代码已更新但页面仍显示旧内容”,基本是多层缓存叠加导致的。问题不在代码本身,而在缓存没被正确清除或绕过。核心要分清:哪一层缓存挡住了新代码?然后针对性处理。
先确认是不是OPcache在作怪
这是部署后最常被忽略的元凶。OPcache把PHP脚本编译后的字节码存在内存里,即使你替换了.php文件,它默认可能每2秒才检查一次文件是否改动(opcache.revalidate_freq=2),或者干脆不检查(生产环境常设为0)。
- 开发/测试阶段:编辑php.ini,设为
opcache.validate_timestamps=1且opcache.revalidate_freq=0,让每次请求都校验文件时间戳 - 上线后紧急修复:临时调用
opcache_reset()函数(写个独立PHP文件访问即可),或重启PHP-FPM服务 - 验证是否生效:访问含
var_dump(opcache_get_status()['opcache_enabled']);的页面,返回true且memory_usage.used_memory有值,说明OPcache在工作
浏览器和CDN缓存不能靠PHP头完全控制
你在PHP里用header("Cache-Control: no-cache")只能影响浏览器,对CDN、反向代理(如Cloudflare、宝塔面板自带缓存、Nginx fastcgi_cache)完全无效——它们在请求到达PHP前就返回了旧响应。
- 浏览器端:强制硬刷新(Ctrl+F5 或 Cmd+Shift+R),或打开开发者工具→Network标签页→勾选“Disable cache”
- CDN/代理层:登录对应平台后台,手动“清除缓存”或“Purge Everything”;部分免费主机需等待其自动过期(可能长达数小时)
- 不建议长期依赖PHP头禁用缓存:它只对直连有效,且可能干扰正常静态资源缓存策略
数据与应用层缓存要主动清理
如果你用了Redis、APCu或框架内置缓存(如Laravel的config/view缓存),它们不会随PHP文件更新自动失效。旧配置、旧模板、旧查询结果仍会继续生效。
- Redis/Memcached:执行
redis-cli FLUSHDB(清当前库)或FLUSHALL(清全部),注意这会影响其他功能 - Laravel项目:运行
php artisan config:clear && php artisan view:clear && php artisan cache:clear - 自定义文件缓存:检查
/storage/cache或caches/目录,删除其中所有内容(或用find /path/to/cache -type f -mmin +60 -delete删1小时前的旧文件)
部署时加一步“缓存刷新”自动化
人工清缓存容易遗漏,尤其在多服务器或容器环境下。建议把缓存清理纳入部署流程:
- Git钩子或CI/CD脚本末尾加入:
curl -s http://yoursite.com/clear_opcache.php(该文件仅限内网访问,内容为opcache_reset()) - 使用统一缓存前缀,例如Redis中所有键加
v2.3.1:前缀,上线时直接redis-cli KEYS "v2.3.1:*" | xargs redis-cli DEL - 模板或配置类缓存,可在文件名或键中嵌入git commit hash,确保变更即失效
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











