composer dump-autoload 不支持 --apcu 参数,APCu 仅缓存 classmap 查找结果;真正预加载需用 opcache.preload 配合 dump-autoload -o -a 生成的 classmap,在 preload 脚本中 require_once 各类文件。

composer dump-autoload 时加 --apcu 或 --apcu-bc 参数没用?
因为 composer dump-autoload 本身不支持 --apcu 这类参数——这是常见误解。APCu 预加载和 Opcache 预加载是两回事,Composer 原生只参与生成自动加载映射,不直接控制 APCu 缓存行为。
真正起效的是在生成的 vendor/autoload.php 中手动启用 APCu(需扩展已安装),或更推荐:用 Opcache 的 opcache.preload 功能做真正的预编译加载。
- APCu 缓存的是
classmap查找结果(路径 → 文件映射),不能跳过 PHP 解析和编译 - Opcache preload 是把 PHP 文件提前解析、编译、常量折叠、JIT(如启用)后驻留内存,启动即用
- Composer 的
dump-autoload --optimize(即-o)仅合并 classmap,减少文件 I/O,但不触发 Opcache 预加载
如何正确配置 opcache.preload 加载 Composer 自动加载逻辑
关键不是让 Opcache “preload Composer”,而是让 preload 脚本显式 require 所有核心类文件,同时兼容 Composer 的自动加载机制。
标准做法是:先用 composer dump-autoload -o -a 生成优化后的 classmap,再写一个 preload 脚本,遍历该 classmap 并 require_once 每个文件(Opcache 会自动编译它们)。
opcache.preload=/path/to/preload.php
preload.php 示例(精简版,生产环境建议加异常过滤和白名单):
$file) {
if (file_exists($file)) {
require_once $file;
}
}
}
- 必须确保
opcache.enable=1且opcache.preload指向该文件 -
opcache.preload_user必须设为运行 Web 服务的用户(如www-data),否则权限拒绝 - preload 脚本中不能使用动态类名、
eval、未定义函数,否则 Opcache 启动失败
为什么 vendor/autoload.php 不能直接作为 preload 文件?
因为 vendor/autoload.php 是一个“加载器入口”,它内部依赖运行时判断(如 PHP_SAPI)、动态注册 spl_autoload_register、甚至调用 include 其他 loader 文件——这些行为在 Opcache preload 阶段被禁止。
- Opcache preload 执行时机早于任何请求,此时
$_SERVER、$_ENV等超全局变量不可靠 -
spl_autoload_register()在 preload 阶段调用会报Warning: spl_autoload_register(): Cannot register autoload function in preloaded script - 直接
require vendor/autoload.php会导致 preload 失败并静默跳过,Opcache 日志里会出现Failed to preload
验证 preload 是否生效的三个命令
别只看 phpinfo() 里 opcache.preload 的路径是否显示,要确认实际加载效果:
- 检查 Opcache 缓存状态:
php -r "print_r(opcache_get_status()['preload_statistics']);",看scripts_preloaded数量是否增长 - 查看是否命中预加载类:
php -r "var_dump(opcache_is_script_cached('/path/to/SomeClass.php'));"返回true表示已预编译 - 对比启停 preload 后的
microtime(true)初始化耗时(尤其 Laravel/Symfony 应用),通常可降 20–40ms
注意:修改 preload 脚本后必须重启 PHP-FPM 或 Apache,Opcache 不会自动重载它。










