APCu缓存需同时满足extension=apcu.so、apc.enabled=1、apc.enable_cli=1才生效;--apcu仅缓存类名→路径映射,依赖classmap且仅在FPM中有效,CLI下不持久。

加了 --apcu 不代表 APCu 缓存就生效,绝大多数情况它根本没写进去,甚至压根没触发缓存逻辑。
为什么 composer dump-autoload --apcu 总是静默失败
这个命令本身不校验 APCu 是否可用,只尝试写入 —— 一旦 apc.enable_cli=0(PHP CLI 默认值),apcu_store() 就会静默返回 false,缓存完全没存进去,但命令仍成功退出。你看到的只是“生成了 autoload_static.php”,不是“APCu 缓存已就位”。
- 运行
php -i | grep "Loaded Configuration File"确认 CLI 实际加载的php.ini路径 - 检查该配置文件中是否同时存在:
extension=apcu.so(或.dll)、apc.enabled=1、apc.enable_cli=1 - 漏掉
apc.enable_cli=1是最常见原因:Web 环境能用 APCu,CLI 下却完全不可写 - 执行
php -r "var_dump(apcu_store('test', 'ok'));",若输出bool(false),说明 CLI 下 APCu 写入已失效
--apcu 只缓存类名→路径映射,不加速文件加载本身
APCu autoloader 干的事非常窄:把 App\Http\Controllers\HomeController → /var/www/src/Http/Controllers/HomeController.php 这个映射关系存进内存。它不碰文件内容、不跳过 require、也不影响 OPcache 行为。
- 真正省下的是每次
new或class_exists()时的字符串前缀匹配 + 目录遍历 +file_exists()调用 - 如果项目没开
--optimize-autoloader(即没生成autoload_classmap.php),--apcu几乎无效 —— 因为它只缓存 classmap 数据,而 classmap 本身不存在 - 验证是否真缓存了:运行
php -r "print_r(apcu_cache_info('user'));",查找 key 含composer-apcu-autoloader-的条目 - 注意:CLI 下跑完
dump-autoload --apcu,缓存只存在于当前进程生命周期内;FPM worker 才是实际读缓存的地方
生产环境别单独用 dump-autoload --apcu
它只刷新 PSR 映射逻辑,不重建 classmap,也不清旧缓存。在部署流水线里直接用,极易导致缓存错乱或类找不到。
- 推荐做法是:部署时统一执行
composer install --no-dev --optimize-autoloader --classmap-authoritative --apcu-autoloader -
--apcu-autoloader(两个短横线)才是正确参数,--apcu是dump-autoload子命令专用,install命令不认它 - 执行后务必重启 PHP-FPM 进程,或手动调用
apcu_clear_cache('user')清旧缓存,否则可能命中过期映射 - 如果项目用了
"files"类型自动加载(如全局 helper 函数),它们不会进 APCu 缓存,也无需进 —— 这部分靠 OPcache 缓存文件本身更有效
APCu autoloader 的价值只在 PHP-FPM 长生命周期进程中体现,且高度依赖 apc.shm_size 是否够大、apc.ttl 是否合理、以及 classmap 是否真实完整 —— 任何一环断掉,它就退化成普通文件查找,还多了一次无意义的 apcu_fetch() 调用。


















