APCu autoloader 是 Composer 利用 APCu 用户缓存预存类名到文件路径映射的机制,仅缓存“类名→文件路径”的查找表,不缓存类文件内容;启用需同时使用 --apcu-autoloader 和 --optimize-autoloader,并确保 APCu 用户缓存可用。

APCu autoloader 是什么,它缓存了什么?
Composer 的 --apcu-autoloader 参数会在生成自动加载器时,把类名到文件路径的映射关系写入 APCu 用户缓存(而非每次 require 时重新解析 vendor/composer/autoload_classmap.php)。它不缓存类文件内容,只缓存“哪个类在哪个文件里”这张查找表。
这意味着:类文件本身仍需 PHP 解析执行,但 Composer 不再需要遍历 classmap 数组或匹配 PSR-4 前缀规则——直接从 APCu 中 get 一次就拿到完整路径。
- 适用场景:大量类、稳定依赖、启用了 APCu 扩展(且未禁用用户缓存)
- 不适用场景:开发中频繁增删类、CLI 环境(APCu 默认不启用用户缓存)、Docker 容器未配置
apc.enable_cli=1 - 注意:
--apcu-autoloader仅影响 classmap 和 PSR-4/PSR-0 映射,不加速autoload-files或函数加载
如何正确启用并验证是否生效?
启用前确保 APCu 已安装且用户缓存可用:
php -m | grep apcu php -r "var_dump(apcu_enabled());" // 必须输出 bool(true)
然后重新生成 autoloader:
composer dump-autoload --apcu-autoloader --optimize-autoloader
关键点:
-
--optimize-autoloader必须同时使用,否则 classmap 不会生成,APCu 缓存无数据可存 - Web 环境下首次请求会写入 APCu;CLI 下需手动设置
apc.enable_cli=1(否则apcu_store()静默失败) - 验证是否写入:访问页面后执行
php -r "print_r(apcu_fetch('composer:autoload'));",应返回非空数组
常见失效原因和性能陷阱
开了参数却没提速?大概率掉进了这些坑:
- APCu 内存不足:默认
apc.shm_size=32M,大型项目 classmap 超过 10MB 后可能被挤出,检查apcu_cache_info()['mem_size']和num_hits/num_misses - APCu TTL 设置为 0:某些系统(如 Ubuntu php-apcu 包)默认
apc.ttl=0,导致缓存立即过期;建议显式设为apc.ttl=7200 - 多 PHP-FPM 进程间缓存不共享:APCu 是进程级缓存,每个 worker 独立一份;冷启动时部分请求仍走慢路径,属正常现象
- 使用了
composer install --no-autoloader或后续又执行了普通dump-autoload:会覆盖掉 APCu 版本,缓存失效
与 OPcache 的关系:不是替代,而是协作
APCu autoloader 和 OPcache 解决的是不同层级的问题:
- OPcache 缓存 PHP 字节码(
.php文件编译结果),对所有 PHP 代码生效 - APCu autoloader 只缓存 Composer 的类定位逻辑,减少字符串匹配和数组查找开销
- 两者可共存:OPcache 加速文件执行,APCu 加速“找文件”过程;但若 OPcache 已启用且命中率高,APCu 带来的提升可能从 15% 降至 3–5%
- 不要为了 APCu autoloader 关闭 OPcache —— 后者收益大得多
真正影响效果的,往往是 APCu 的配置细节和部署环境的一致性,而不是开关本身。比如 CLI 场景下忘记开 apc.enable_cli,或者容器里 APCu 根本没装,参数就只是个无效开关。











