APCu autoloader 不会自动启用,必须在 composer install 或 update 时显式添加 --apcu-autoloader 参数(且需配合 --optimize-autoloader),并确保 PHP CLI 模式下 apc.enabled=1 和 apc.enable_cli=1 均生效,否则静默降级为文件加载。

这里有个关键点很容易被忽略:APCu autoloader 不会自动启用。哪怕你确认扩展已安装,也执行了 composer install,只要没有显式触发,它就完全不会工作。
为什么 composer install 后 APCu 没生效?
问题的根源,往往不是 Composer 不支持,而是我们压根没要求它启用。APCu autoloader 本质上是一个可选开关,并非默认行为。
- 必须在执行
composer install或composer update时,明确加上--apcu-autoloader参数(注意是两个短横线)。事后想用dump-autoload命令补救是行不通的。 composer dump-autoload命令本身不识别--apcu-autoloader参数,强行添加会直接报错:Unrecognized option。- 如果项目目录下已经存在旧的
vendor/autoload.php文件,即便加了参数也可能不会覆盖。稳妥的做法是先删除vendor/目录,或者在命令中使用--no-scripts来避免旧逻辑的干扰。 - 它的作用范围仅限于 Composer 自动生成的 autoload 逻辑(即
vendor/autoload.php加载的路径)。任何手动require的文件都会完全绕过这个缓存机制。
CLI 下报 “APCu is not enabled” 怎么办?
遇到这个错误提示,通常不是 PHP 扩展没装,而是 CLI(命令行)模式下 APCu 实际上并未被启用。Web 环境(如 PHP-FPM)和 CLI 环境可能使用不同的 php.ini 配置文件,设置互不影响。
- 首先,运行
php -i | grep “Loaded Configuration File”命令,查看 CLI 模式实际加载的配置文件路径。 - 确认该
php.ini文件中已启用 APCu 扩展(Linux/macOS 是extension=apcu.so,Windows 是extension=php_apcu.dll),并且没有被注释掉。 - 必须确保配置中包含
apc.enabled=1(注意值是数字1,而不是字符串On)和apc.enable_cli=1。后者尤其容易被忽略,但在 CLI 下生成缓存是必须开启的。 - 一些 Docker 镜像或云环境默认会关闭
apc.enable_cli,需要手动补上。修改后,记得重启终端会话。用php -v验证是无效的,必须使用php -i来检查配置是否生效。
怎么验证 APCu autoloader 真正在跑?
别只看命令执行时有没有报错,得检查生成的代码和运行时的实际行为。
- 打开
vendor/autoload.php文件,搜索apcu_fetch或composer.autoload.这样的字符串。如果找不到,基本可以断定它根本没被启用。 - 在项目代码中添加一行调试语句:
,如果返回true,才说明缓存成功写入了。 - 检查
apcu.stat的配置:如果设为1,APCu 会在每次请求时检查源文件是否被修改,这会导致缓存机制被绕过。在生产环境中,务必将其设置为0。 - APCu 的缓存键是基于项目路径哈希生成的。一旦更换项目目录,或者修改了
composer.json中的 autoload 配置,旧的缓存就会自动失效。这个过程不会报错,很容易让人误判为“配置没生效”。
APCu autoloader 到底加速哪一步?
它的作用范围非常明确:只缓存“类名到文件路径”的映射关系(也就是 autoload_classmap.php 和 autoload_psr4.php 这些文件的解析结果)。它不缓存文件内容本身,也不会跳过 require_once 的调用。
- 它最适合依赖关系稳定、classmap 条目超过 5000+ 的生产环境。对于小型项目,或者在开发阶段频繁修改类文件的情况,收益极低,甚至可能因为缓存未及时清理而导致
Class not found错误。 - 需要明确它和 OpCache 的关系:两者是正交的。OpCache 负责缓存操作码(opcode),而 APCu autoloader 负责缓存映射表,它们可以共存,但作用完全不同,别混淆了。
- 在 PHP-FPM 模式下,worker 进程间可以共享 APCu 缓存。但在 CLI 模式下,每次执行都是一个独立的进程,因此用
php -r 'require...'这类命令来测试“加速效果”是测不出来的,这是正常现象。 - 部署后如果出现类找不到的情况,很大概率是
vendor/目录更新了,但 APCu 中的旧缓存没有被清理。稳妥的做法是在部署脚本中加入一行:php -r “apcu_clear_cache('user');”。
最后,还有一个最容易被跳过的关键点:APCu autoloader 必须和 --optimize-autoloader(或其简写 -o)参数一起使用才会生效。如果单独使用 --apcu-autoloader,Composer 会静默忽略它,直接降级为普通的文件加载方式。
