opcache.preload必须显式配置绝对路径才生效,PHP≥7.4且opcache.enable=1仅是前提;需在php.ini[opcache]段落中设置opcache.preload=/绝对路径/preload.php,路径错误或权限不足将静默失败。

opcache.preload 配置必须显式写绝对路径
预加载不会自动生效,哪怕 PHP ≥ 7.4 且 opcache.enable=1 已开启。关键在于 opcache.preload 必须在 php.ini 中明确指定一个**绝对路径**的 preload.php 文件,空值、相对路径(如 ./preload.php)、波浪号(~/preload.php)全部无效,且不报错——只会静默跳过。
- 用
phpinfo()找到 Loaded Configuration File 路径,编辑该文件,在[opcache]段落下添加:opcache.preload=/var/www/myapp/preload.php - 确保该路径对 PHP-FPM worker 用户(如
www-data)可读:chown www-data:www-data /var/www/myapp/preload.php且chmod 644 - 修改后必须完整重启 PHP-FPM:
sudo systemctl restart php74-fpm(不是 reload)
preload.php 里只能 include_once 或 opcache_compile_file()
preload.php 在服务启动时执行一次,任何副作用操作都会导致 PHP-FPM 启动失败或行为异常。它不是普通脚本,而是“让 PHP 提前编译并链接类定义”的指令集。
- 只允许使用
require_once或include_once加载类文件;opcache_compile_file()更安全(不执行代码,仅编译) - 禁止:
new实例化、SomeClass::init()、echo、file_get_contents()、class_exists()等运行时检测 - 若用 Composer,可
require_once __DIR__ . '/vendor/autoload.php',但前提是该 autoload.php 不含副作用(现代版本满足) - 批量加载时过滤非实现类:
RegexIterator排除.*Test\.php$、.*Interface\.php$、.*Stub\.php$等,否则类链接失败会中断启动
依赖顺序错误会导致 Class not found
预加载不是简单把文件塞进内存,而是要完成类之间的符号链接(比如子类依赖父类、实现接口、使用 trait)。如果父类没被先加载,子类预加载就会失败,PHP-FPM 直接启动不起来,日志里只有模糊的 “Segmentation fault” 或 “Failed to preload”。
- 不能靠目录遍历顺序碰运气;应按类依赖拓扑序加载:先框架核心(
Illuminate/Foundation/Application.php),再服务提供者,最后业务类 - Laravel 项目推荐优先加载
vendor/laravel/framework/src/Illuminate下所有.php文件,再处理app/和bootstrap/ - 用
opcache_get_status()['preloaded_scripts']检查实际成功预加载了哪些文件,确认关键类是否在列表中 - 开发阶段可临时设
opcache.validate_timestamps=1,避免改完代码忘了重启 PHP-FPM 导致白屏
别盲目 preload vendor 全量文件
“预加载所有 vendor 文件”看似省事,实则容易触发内存溢出、类名冲突或链接失败,尤其当包里混有测试类、条件定义函数、动态 eval 逻辑时。
立即学习“PHP免费学习笔记(深入)”;
- 优先预加载 Laravel 框架本身(
vendor/laravel/framework/src)和你项目直接use的第三方库主类(如monolog/monolog的Logger.php) - 跳过
tests/、examples/、stubs/、resources/目录,也避开composer/autoload_*.php这类生成器脚本 - 内存消耗真实可见:
opcache.memory_consumption至少设为256,预加载后opcache_get_status()['memory_usage']['used_memory']通常增加 20–80MB - Windows 系统不支持预加载,别在本地开发环境折腾;只在 Linux + PHP-FPM 生产环境启用
new 或 if 块里的函数定义,就退化成普通 include,还可能破坏进程稳定性。



















