
确认 OPcache 是否真加载了,别被 phpinfo 蒙过去
PHP 8.5 确实把 OPcache 编译进核心了,但 opcache.enable=0 仍是默认值——也就是说,它“存在”,但“关着”。很多人改完 php.ini 就去刷 phpinfo(),看到 OPcache 区块就以为成功了,结果请求压根没走缓存。
真正有效的验证方式只有两个:
- 终端执行
php -m | grep opcache,有输出才说明模块已加载 - 再跑
php -i | grep "opcache.enable",必须返回opcache.enable => On,而不是Off或根本没这行
常见错误:改了 CLI 模式的 php.ini(比如 /etc/php/8.5/cli/php.ini),却忘了 Web SAPI 用的是另一个文件(如 /etc/php/8.5/apache2/php.ini 或 /etc/php/8.5/fpm/php.ini)。php --ini 输出的 “Loaded Configuration File” 才是你要改的那个。
启用 + 必设参数,缺一不可
只写 opcache.enable=1 是无效配置。PHP 8.5 的 OPcache 对内存、文件数、时间戳校验极度敏感,缺关键参数会导致缓存命中率极低,甚至“开了等于没开”。
立即学习“PHP免费学习笔记(深入)”;
在 php.ini 中必须显式添加或取消注释以下几项:
-
zend_extension=opcache(Linux/macOS)或zend_extension=php_opcache.dll(Windows),注意不是extension=opcache opcache.enable=1-
opcache.memory_consumption=128(单位 MB;小项目 64 够用,Laravel/WordPress 建议 256) -
opcache.max_accelerated_files=10000(必须 ≥ 项目中*.php文件总数,可用find /var/www/html -name "*.php" | wc -l估算) -
opcache.validate_timestamps=1(生产环境也别关!否则改代码不生效) -
opcache.revalidate_freq=2(开发环境可设为 0,但上线后设为 0 会每请求都 IO,拖慢性能)
漏掉 opcache.max_accelerated_files 是最常踩的坑——缓存池满了就会频繁淘汰,脚本反复编译,CPU 反而更高。
重启服务不是 reload,必须 kill 进程再拉起
改完 php.ini 后,systemctl reload apache2 或 nginx -s reload 不会重新加载 OPcache。它只重读配置,但 OPcache 是在 PHP 进程启动时初始化的。
正确操作取决于你的运行模式:
- Apache + mod_php:必须
systemctl restart apache2 - Nginx + PHP-FPM:必须
systemctl restart php8.5-fpm(版本号要对得上) - phpstudy / XAMPP:点“重启服务”按钮,不能只点“重载配置”
验证是否生效:重启后立刻执行 php -m | grep opcache,如果没输出,说明进程没真正重启,或者路径配错了。
怎么知道它真在干活?用 opcache_get_status() 看实时数据
phpinfo() 只告诉你“有没有”,不告诉你“好不好”。真正判断 OPcache 是否健康,得看命中率和缓存脚本数。
新建一个 opcache-status.php,内容如下:
<?php
if (function_exists('opcache_get_status')) {
$status = opcache_get_status();
echo "命中率: " . round($status['opcache_statistics']['hit_rate'], 2) . "%\n";
echo "缓存脚本数: " . $status['opcache_statistics']['num_cached_scripts'] . "\n";
echo "内存使用: " . round($status['memory_usage']['used_memory_percent'], 1) . "%\n";
} else {
echo "opcache_get_status() 不存在\n";
}
?>
刚重启后命中率可能是 0%,多刷几次页面,理想状态是命中率 > 95%,缓存脚本数接近你设的 opcache.max_accelerated_files 值。如果长期卡在 30%–50%,大概率是 max_accelerated_files 设太小,或用了大量 eval() / create_function() ——这些动态代码不会进缓存。
最后提醒一句:JIT 在 PHP 8.5 里是独立开关(opcache.jit=1255),它和 OPcache 不是一回事。先确保 OPcache 正常工作,再考虑 JIT。否则 JIT 编译的机器码连缓存都进不去。











