composer dump-autoload 是重生成自动加载映射表,非刷新缓存;改类位置、命名空间或 autoload 配置后必须执行,否则新类无法加载。

composer dump-autoload 不是“刷新缓存”,而是重生成自动加载映射表——你改了类文件位置、命名空间或 composer.json 里的 autoload 配置,它才真正起作用。
为什么 new User() 报错 Class not found?
不是 Composer 没加载,而是 PSR-4 映射根本没命中:namespace App\Controller 对应 "App\": "src/",那 User 类就必须在 src/User.php;如果它实际在 src/Models/User.php,但命名空间却是 App\User,就必然失败。
- PSR-4 是机械字符串替换:砍掉前缀
App\,剩下User→ 拼成src/User.php;若剩下的是Models/User,那命名空间必须是App\Models\User -
src/结尾必须有斜杠,不能写成src或/src/;路径大小写敏感,Windows 下常因Src/和src/混用导致失效 - 类文件名必须严格等于类名 +
.php,class UserService→ 必须叫UserService.php,不能是userservice.php或user_service.php - 改完代码或配置后,不执行
composer dump-autoload,vendor 里的autoload_psr4.php还是旧的映射,自然找不到新类
什么时候该用 files 而不是 PSR-4?
当你有一堆纯函数、常量或启动逻辑(比如 src/helpers.php),没有 class 声明,也不打算封装成类时,files 是唯一正解——它会在引入 vendor/autoload.php 时无条件 require_once 这些文件。
- 配置写在
composer.json的"autoload": {"files": ["src/helpers.php"]},路径是相对于composer.json所在目录 - 多个文件按数组顺序加载,注意函数重定义风险(如两个文件都定义了
str_slug()) - 改完
files列表,必须运行composer dump-autoload,否则新增的文件不会被注册 - 它和类自动加载无关,不能用来加载 class;反过来,也别把类文件塞进
files,会触发 “Cannot declare class X, because the name is already in use”
composer dump-autoload -o 真的更快,但有代价
加 -o(即 --optimize)会让 Composer 扫描所有可加载类,生成一张静态 autoload_classmap.php 表,运行时直接查数组,跳过路径拼接和 is_file() 判断——线上环境提速明显。
- 但扫描只覆盖
psr-4和classmap配置里明确声明的路径,漏一个目录,里面的新类就永远加载不到 - 开发中慎用:改一个类文件就得重新
dump-autoload -o,否则本地跑不通;调试阶段建议用默认模式 - 更稳妥的生产部署方式是:
composer install --no-dev --optimize-autoloader,它比单独dump-autoload -o多做校验(比如检查composer.lock),不易出错
classmap 是老代码的救命稻草
当你的项目里有大量无命名空间、类名和文件名不一致、甚至带下划线的老 PHP 文件(比如 DB_Connection.php 里定义 class DB_Connection),PSR-4 根本玩不转——这时 classmap 是最务实的选择。
- 配置示例:
"classmap": ["legacy/", "utils/common.php"],Composer 会递归扫描legacy/下所有.php文件,提取class声明并建立类名到路径的映射 - 新增类后必须手动运行
composer dump-autoload,否则不会被发现——它不像 PSR-4 那样靠规则推导,而是靠“快照” - 不支持命名空间别名,也不能处理动态生成的类(比如 PHPUnit Mock 类),生产环境加
--classmap-authoritative后,一旦漏扫就直接Fatal error
Class not found。










