APCu autoloader 将类名→路径查找从每次请求的CPU+IO操作降为一次内存读取,但仅当PHP进程复用(如PHP-FPM)、apc.enable_cli=1(CLI需显式开启)、且配合--optimize-autoloader生成完整classmap时才生效;否则缓存写入失败或无法命中。

APCu autoloader 不是“让类加载变快一点”,而是把类名→文件路径的查找过程从每次请求都执行的 CPU+IO 操作,变成一次内存读取——只要 APCu 缓存命中,new SomeClass 就不再触发 file_exists()、字符串前缀匹配或目录遍历。
为什么 class_exists() 或 new 实例后没走 APCu?
常见现象:加了 --apcu-autoloader,但 strace -e trace=openat php -r "new PDO();" 依然看到大量文件打开;或 apcu_cache_info('user') 返回空数组。核心原因只有两个:
- PHP 进程未复用 —— CLI 下运行
composer install --apcu-autoloader后直接php -r "new Foo();",缓存写入了但进程退出,下次请求是全新进程,缓存不可见 -
apc.enable_cli=0(默认值)导致 CLI 场景下apcu_store()静默失败,而 Web 环境(如 PHP-FPM)里又没重新生成过缓存 - 没同时用
--optimize-autoloader:APCu autoloader 只缓存 classmap 数据,而 classmap 本身必须由--optimize-autoloader触发生成;单独加--apcu-autoloader是空转
composer install --apcu-autoloader 和 dump-autoload --apcu-autoloader 的区别
两者本质不同,不能混用:
-
composer install --apcu-autoloader:在安装依赖时,扫描全部 autoload 配置(PSR-4、classmap、files),生成完整autoload_classmap.php,再把它序列化写入 APCu —— 这是生产部署唯一推荐的方式 -
composer dump-autoload --apcu-autoloader:只刷新 PSR 映射和autoload_static.php,不重建 classmap;若项目没配"classmap": ["src/"]或没启用--classmap-authoritative,它几乎不产生有效缓存数据 - 错误组合:
composer install --apcu-autoloader后又执行composer dump-autoload(无参),会覆盖掉 vendor/autoload.php 中的 APCu 加载逻辑,降级回纯文件查找
APCu 缓存失效却查不到原因?重点看这三处
缓存“存在但不生效”比“完全没写入”更难排查:
-
apc.shm_size不足:大型项目 classmap 数组常超 10MB,而默认apc.shm_size=32M可能被其他用户缓存挤占;检查apcu_cache_info()['mem_size']和num_misses是否持续增长 -
apc.ttl=0:某些系统(如 Ubuntu 的php-apcu包)默认设为 0,导致缓存写入即过期;应显式设为apc.ttl=7200 - 多应用共用 APCu 实例:若多个 Laravel/Symfony 项目跑在同一 PHP-FPM pool,缓存 key 冲突,旧映射残留;需配置
apc.namespace="myapp_"隔离
真正起效的不是参数本身,而是 classmap 数据是否完整、APCu 是否被进程共享、以及缓存生命周期是否可控——这些点漏掉任何一个,--apcu-autoloader 就只是个开关而已。



















