启用classmap优化需用composer install -o,它生成autoload_classmap.php实现查表加载;注意不存在”optimize-with-classmap”配置项,且需权衡类数量、opcache及内存占用。

composer install 时怎么启用 classmap 优化
直接加 --optimize-autoloader(或简写 -o)参数就行,它会触发 Composer 生成扁平的 classmap 映射,跳过 PSR-4/PSR-0 的文件扫描逻辑,提升自动加载性能。
常见错误现象:加了 "optimize-with-classmap": true 到 composer.json 却没生效——这个配置项根本不存在,Composer 官方不认这个键名,属于混淆了旧版文档或第三方插件的写法。
-
composer install -o:生产环境部署时必加,尤其在无 OPcache 或容器冷启动场景下效果明显 -
composer dump-autoload -o:开发中修改了类文件路径后,可单独重生成 classmap,不用重装依赖 - 如果项目用了
psr-4但又混入大量散列的.php文件(比如旧模块),-o会把它们一并扫进 classmap,反而增大autoload_classmap.php体积,得权衡
classmap 生成后实际影响哪些文件
执行 -o 后,Composer 会写入两个关键文件:vendor/autoload.php 和 vendor/composer/autoload_classmap.php。后者是纯数组,key 是类名,value 是绝对路径,运行时直接查表,不走 file_exists()。
注意:只有被 Composer 扫描到的 PHP 文件才会进 classmap。默认只扫 autoload.classmap 配置项里声明的目录,以及 autoload.psr-4 下每个命名空间对应的路径——但不会扫 vendor/ 外的任意目录,除非你显式加进 classmap 数组。
- 如果你在
composer.json里写了"classmap": ["src/", "lib/"],那这两个目录下所有.php文件都会被递归索引,无论是否含class关键字 - PSR-4 映射的目录,即使没写进
classmap,也会被-o一并扫描(这是默认行为),所以别误以为“只扫 classmap 配置项” - 生成的
autoload_classmap.php里不含注释、不格式化,体积可能达 MB 级——对内存敏感的 CLI 脚本或 serverless 环境要留意
为什么有时候加了 -o 反而变慢
不是所有场景都适合 classmap。当类文件极多(比如 >10k)、且实际运行中只用到其中一小部分时,classmap 会把整个映射表一次性载入内存,而 PSR-4 按需查找反而更轻量。
典型踩坑点:在 docker 构建阶段用 composer install -o,但镜像里没开 OPcache;结果每次请求都得反序列化几 MB 的 classmap 数组,比动态查找还耗 CPU。
- Web 请求中,OPcache 开启且启用
opcache.save_comments=0和opcache.load_comments=0,classmap 才真正高效 - laravel 的
php artisan optimize(老版本)底层就是调dump-autoload -o,但新版本已移除,说明框架也倾向按需加载 + OPcache 组合 - 用
strace -e trace=openat php index.php 2>&1 | grep autoload_classmap可验证是否真读了 classmap 文件——有时你以为启用了,其实 autoloader 还在走 PSR-4 fallback
classmap 优化不是开关一按就万事大吉的事,它把“运行时成本”转移到了“构建时和内存占用”上,具体要不要用,得看你的部署环境、类规模、是否启用 OPcache,还有监控数据里自动加载那块到底卡不卡。