预加载需php≥7.4且opcache.enable=1,必须配置绝对路径的opcache.preload,preload.php仅允许require_once或opcache_compile_file(),禁止运行时操作,修改后须重启php-fpm验证。

预加载不会自动生效,哪怕 PHP 7.4 已启用 OPcache —— 必须显式配置绝对路径的 opcache.preload,且 preload.php 里不能有任何运行时副作用,否则 PHP-FPM 启动失败或静默跳过。
确认 PHP 版本与 OPcache 是否真正启用
预加载依赖两个硬性前提:PHP >= 7.4 且 opcache.enable=1。但很多人改了 CLI 的 php.ini(如 /etc/php/7.4/cli/php.ini),却没动 FPM 实际加载的那份。
- 新建
info.php,内容为<?php phpinfo(); ?>,用浏览器访问它 - 搜索
Loaded Configuration File,拿到真实路径(例如/www/server/php/74/etc/php.ini) - 编辑该文件,在末尾添加
[opcache]段,并确保有:zend_extension=opcache.so和opcache.enable=1 - 改完后必须执行
sudo systemctl restart php74-fpm(不是 reload,也不是只重启 Nginx)
opcache.preload 必须写绝对路径,且权限正确
opcache.preload 不接受相对路径、./、~/ 或空值;填错或路径不可读,PHP-FPM 启动时完全不报错,只会跳过预加载 —— 这是最常见的“配了但没用”原因。
- 在刚才确认的
php.ini的[opcache]段下添加:opcache.preload=/var/www/myapp/preload.php - 确保该文件对 PHP-FPM worker 用户(如
www-data或www)可读:chown www-data:www-data /var/www/myapp/preload.php && chmod 644 /var/www/myapp/preload.php - 若服务器以 root 启动后降权,还需加一行:
opcache.preload_user=www-data(否则会因权限拒绝而静默失败)
preload.php 只能做编译,不能做任何运行时操作
这个文件不是普通脚本,是 PHP 启动时一次性执行的“编译指令集”。一旦出现 new、echo、file_get_contents()、class_exists() 或未定义的函数调用,PHP-FPM 就可能崩溃或启动卡住,日志里往往只有 Segmentation fault 或无提示退出。
- 只允许使用:
require_once、include_once、opcache_compile_file() - 推荐优先用
opcache_compile_file():它只编译不执行,更安全;例如:opcache_compile_file(__DIR__ . '/vendor/autoload.php'); - 批量加载时,用
RegexIterator过滤掉测试类、接口、桩类:/.*Test\.php$/i、/.*Interface\.php$/i - Laravel 等框架要按依赖顺序加载:先
vendor/laravel/framework/src/Illuminate,再app/,最后bootstrap/;否则子类找不到父类直接启动失败
验证预加载是否成功,而不是只看配置有没有写
配置写对 ≠ 预加载成功。很多项目看似跑起来了,但关键类根本没进内存 —— 因为路径拼错、类依赖断裂、或 autoload.php 本身含副作用(老版本 Composer 可能有)。
- 部署后执行:
php -r "print_r(opcache_get_status()['preloaded_scripts'] ?? []);" - 检查返回数组里是否有你期望的类文件路径(如
/var/www/myapp/vendor/laravel/framework/src/Illuminate/Foundation/Application.php) - 如果为空或远少于预期,重点查:
preload.php中的路径是否真实存在、是否被RegexIterator过滤掉了、是否有opcache_compile_file()返回false(可加简单判断:if (!opcache_compile_file($file)) { error_log("Failed to preload: $file"); }) - 注意:修改
preload.php或源文件后,必须重启php74-fpm才生效,刷新页面或opcache_reset()无效
预加载真正的难点不在语法,而在类拓扑关系的梳理和副作用的彻底剥离——一个 echo、一次意外的 file_get_contents(),就足以让整个服务启不来,而且错误信息极其模糊。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











