因为默认不扫描磁盘文件,仅更新psr映射;新增类需加-o参数全量扫描classmap,否则autoload找不到类。

composer dump-autoload 为什么有时“刷新了却还是找不到类”?
因为默认执行 composer dump-autoload 只更新 PSR 映射配置(比如 autoload_psr4.php),并不扫描磁盘上新增/移动/删除的 PHP 类文件。你新加了 AppServicesPaymentService,但它的文件 app/Services/PaymentService.php 没被扫进 classmap,autoloader 就会直接报 Class not found。
- 不加参数:仅重写映射结构,适合改了
"psr-4"路径但没动类文件的情况 - 加
-o(即--optimize):清空旧 classmap,全量扫描所有 autoload 配置目录下的.php文件,生成完整路径数组——这才是真正“刷新” - Linux/macOS 下特别注意:文件名大小写必须和命名空间完全一致,
paymentservice.php≠PaymentService.php
什么时候必须用 composer dump-autoload -o?
不是“偶尔试试”,而是这几类情况不加 -o 就等于白跑:
- 手动新增或删减了类文件(尤其在
app/、src/这类自定义目录下) - 把
src/User.php移到了src/Domain/User.php,且已同步更新composer.json中的 PSR-4 映射 - CI/CD 流水线里先跑了
composer install --no-dev,之后又合入了 dev-only 工具类,需要补扫 - 部署到生产环境后,想确保 autoload 性能最优、无 fallback 查找
验证是否生效,可以快速跑一句:php -r "require 'vendor/autoload.php'; var_dump(class_exists('App\Services\PaymentService'));"
composer du -o 是最常用也最安全的刷新方式
du 是 dump-autoload 的官方简写,和 composer install 一样被 Composer 原生支持。它不下载包、不删 vendor、不碰 composer.lock,只专注重建自动加载逻辑。
-
composer du -o:开发中日常刷新的黄金组合,兼顾速度与准确性 -
composer du -o --no-dev:上线前构建精简版 autoload,排除tests/、dev-tools/等路径 -
composer du -o --classmap-authoritative:进一步关闭文件系统 fallback,类不在 classmap 里就直接报错,避免隐性加载失败
别用 --force ——这个参数根本不存在,反复执行默认命令只会让你更困惑。
容易被忽略的三个底层前提
再猛的 dump-autoload 也救不了配置或结构本身的问题:
-
composer.json中的autoload必须语法合法,路径是相对项目根的**有效路径**,不能写成"../lib"这种跨出项目根的写法 - PSR-4 下,
App\Services\映射到app/,那类AppServicesPaymentService就必须落在app/Services/PaymentService.php,不能是app/services/paymentService.php - 如果用了
classmap字段,记得它只扫描指定目录,且不会递归子目录(除非显式列出或用通配符)
缓存不是问题主因,文件系统状态和配置一致性才是关键。别急着删 vendor,先确认路径、命名、参数三者是否咬合。










