PSR-0 已废弃,迁移到 PSR-4 是唯一稳妥方案:需重排目录使命名空间前缀成为物理路径一部分,如将 "Acme\\Blog\\": "src/" 改为 "Acme\\Blog\\": "src/Acme/Blog/",并确保大小写、路径、双反斜杠完全匹配。

PSR-0 已被废弃,Composer 中继续使用 psr-0 映射会导致自动加载失效、类找不到(Class not found)、或与现代包(如 Laravel、Symfony 组件)冲突。唯一稳妥做法是迁移到 psr-4,并确保目录结构与命名空间严格匹配。
为什么 psr-0 映射会静默失败?
Composer 2.x 虽仍解析 psr-0 字段,但不再生成对应 autoload_static.php 中的 PSR-0 规则;实际运行时依赖回退到文件遍历(慢且不可靠)。更常见的是:你写了 "MyLib\\": "src/",但 MyLib\Foo\Bar 对应的文件路径却是 src/Foo/Bar.php(缺 MyLib 子目录),这在 PSR-0 下曾“凑合能用”,在 PSR-4 下直接报错。
-
psr-0允许命名空间前缀映射到任意目录,类名下划线转斜杠(已淘汰) -
psr-4要求命名空间前缀必须与目录名完全一致,且类名中反斜杠 = 目录分隔符 - Composer install/update 不报错,但
composer dump-autoload -o会跳过无效的psr-0条目
如何将 psr-0 正确迁移到 psr-4?
核心是重排目录结构,让命名空间前缀成为物理路径的一部分。假设旧配置为:
{
"autoload": {
"psr-0": {
"Acme\\Blog\\": "src/"
}
}
}
那么所有 Acme\Blog\* 类必须放在 src/Acme/Blog/ 下,而非 src/ 根目录。迁移步骤:
- 把
src/下原有代码移入src/Acme/Blog/ - 将
composer.json中的psr-0改为psr-4,并补全命名空间前缀路径 - 更新后内容应为:
{ "autoload": { "psr-4": { "Acme\\Blog\\": "src/Acme/Blog/" } } } - 运行
composer dump-autoload -o验证,再用composer show --path acme/blog确认路径正确
常见映射错误与调试方法
最常出问题的是大小写、尾部反斜杠、路径拼写不一致。例如:
- 命名空间写成
acme\blog\(小写),但psr-4键值是"Acme\\Blog\\": "src/Acme/Blog/"→ 自动加载器按字面匹配,失败 -
"Acme\\Blog\\": "src/"缺少子目录 → Composer 不报错,但new Acme\Blog\Post()会尝试加载src/Post.php,而非src/Acme/Blog/Post.php - 使用了相对路径如
"../lib/"→ Composer 只接受相对于composer.json的路径,且不支持上溯到项目根外
调试建议:
- 运行
composer dump-autoload -vvv查看是否打印 “Appending PSR-4 autoloader for …” - 检查生成的
vendor/composer/autoload_psr4.php,确认键名与你的命名空间完全一致(含双反斜杠) - 用
composer validate检查 JSON 格式,它不会校验映射逻辑,但能排除语法错误
真正棘手的不是改配置,而是已有代码里硬编码的 require_once、手动 include 或对 __DIR__ 的路径拼接——这些不会受 Composer 自动加载影响,必须一并清理或重写。










