PSR-4映射需满足:autoload.psr-4为对象,命名空间以“\\”结尾,路径为相对路径;类文件路径必须严格匹配命名空间层级,大小写敏感,且修改后须执行composer dump-autoload。

composer.json 里怎么写 psr-4 映射才生效
必须确保 autoload 下的 psr-4 是一个对象(不是数组),键是命名空间前缀(含结尾反斜杠),值是相对于 composer.json 所在目录的源码路径(支持多个):
{
"autoload": {
"psr-4": {
"App\\": "src/",
"Tests\\": "tests/"
}
}
}
注意两点:一是命名空间末尾的 \\ 不能省,否则 Composer 会当作完全匹配而非前缀匹配;二是路径必须是相对路径,且不以 / 开头,否则运行 composer dump-autoload 会静默失败或报错 Invalid path。
为什么类文件没被自动加载?常见映射错误
最常踩的坑是路径和命名空间对不上。PSR-4 要求类文件路径必须严格反映命名空间层级:
-
App\\Http\\Controller\\HomeController→ 必须位于src/Http/Controller/HomeController.php - 如果实际放在
src/controllers/HomeController.php(小写controllers),即使映射写了"App\\": "src/",也会加载失败 - 文件名大小写敏感:Linux/macOS 下
homecontroller.php≠HomeController.php,类名与文件名必须完全一致 - 命名空间声明(
namespace App\Http\Controller;)必须和composer.json中的前缀拼接后完全匹配
composer dump-autoload 不生效?检查这些点
修改 composer.json 后必须手动刷新自动加载规则,但以下情况会导致刷新无效:
- 没执行
composer dump-autoload,只改了 JSON 就直接跑代码(Composer 不监听文件变更) - 执行了命令但当前目录不是
composer.json所在根目录(会读错配置) - 项目里存在
vendor/autoload.php,但你 include 的是旧版本或别的路径(务必用require __DIR__.'/vendor/autoload.php';) - 有其他 autoload 配置(如
files或classmap)干扰了 PSR-4 解析顺序(优先级:files>classmap>psr-4)
想给目录起别名?PSR-4 本身不支持“别名”,但可以曲线实现
PSR-4 规范不提供类似 “把 src/ 映射成 MyLib\\” 的别名机制——它只认命名空间前缀到路径的单向映射。如果你需要逻辑分组或隐藏真实路径,可行做法只有:
- 在
composer.json中多加一条映射:"MyLib\\": "src/",然后所有类都声明namespace MyLib\Xxx; - 用
repositories+path类型引入本地包,再通过require安装,这样它的autoload由子包自己定义,主项目只管引用命名空间 - 避免用 symlink 或重命名目录来“伪装”别名,Composer 不解析符号链接路径层级,会导致类找不到
真正容易被忽略的是:PSR-4 映射一旦写死,就绑定了命名空间结构;重构时若只改目录不动命名空间,或只改命名空间不动文件位置,都会立刻中断自动加载。










