在 composer.json 的 autoload.psr-4 下直接定义多个键值对,键为以 \ 结尾的命名空间前缀,值为相对于项目根目录的路径(支持字符串或数组);修改后须执行 composer dump-autoload 生效。

composer.json 里怎么写多个 PSR-4 映射
直接在 autoload 的 psr-4 下写多个键值对,每个键是命名空间前缀(必须以 \ 结尾),值是相对于项目根目录的路径(支持数组形式写多个路径)。
常见错误是:命名空间没加结尾反斜杠、路径写成绝对路径、路径末尾多加了 /src 导致类文件实际位置和映射不一致。
示例:
{
"autoload": {
"psr-4": {
"App\\": "app/",
"Tests\\": "tests/",
"Support\\": ["lib/support/", "custom-support/"]
}
}
}
注意:Support\\ 映射了两个目录,Composer 会按顺序查找,前面的优先。
为什么 vendor/autoload.php 生效后新增命名空间不识别
因为 Composer 缓存了自动加载映射表,改完 composer.json 后必须重新生成 autoload 文件。
执行以下命令之一:
-
composer dump-autoload(仅重生成 autoload 文件) -
composer install或composer update(会自动触发 dump)
如果用的是 composer install --no-autoloader,那之后一定得手动补上 dump-autoload,否则新映射完全不生效。
多个 PSR-4 映射冲突时类被谁加载
Composer 按 psr-4 对象中键值对的定义顺序扫描,先匹配到的路径就加载,后面同名类不会被检查。
比如:
"psr-4": {
"App\\": "app/",
"App\\": "legacy/app/"
}
第二个 App\\ 会被忽略(JSON 键重复,实际只保留最后一个),这不是 Composer 的行为限制,而是 JSON 解析本身丢弃了前一个。
正确做法是合并路径:
"App\\": ["app/", "legacy/app/"]
这样 Composer 才会依次在两个目录下找 App\Foo\Bar。
开发时想让某个命名空间临时指向本地目录(如调试包)
用 autoload-dev + repositories 组合更安全,但最轻量的做法是直接在 autoload 里映射本地路径,并确保该路径存在且结构合规。
例如本地调试 MyPackage:
"psr-4": {
"MyPackage\\": "../my-package/src/"
}
注意点:
- 路径必须可读,且目录下要有符合命名空间层级的 PHP 文件(如
MyPackage/Helper.php) - 别在生产环境提交这种指向外部路径的配置,容易引发部署失败
- 如果该包也发布到 Packagist,建议改用
path类型仓库 +require-dev管理,避免污染主 autoload
PSR-4 映射本身不校验文件是否存在,只有运行时 require 到具体类才报错 —— 所以路径写错往往要等第一次 new 实例才暴露。










