PSR-4 不生效的根本原因是 autoload 配置错误导致 Composer 无法正确映射命名空间与路径;必须严格匹配前缀、目录结构、命名空间声明及文件位置,且需手动执行 composer dump-autoload 生效。

composer.json 里的 "autoload" 配置写错,PSR-4 就不会生效——不是 Composer 不认,是它根本没机会去扫描你的类文件。
PSR-4 的映射必须严格匹配命名空间和目录结构
PSR-4 要求:命名空间前缀(如 "App\")对应一个物理目录,该目录下子路径必须与后续命名空间段一一对应。比如:
"autoload": {
"psr-4": {
"App\": "src/"
}
}
那么 App\Http\Controller\HomeController 必须位于 src/Http/Controller/HomeController.php,且文件里必须有 namespace AppHttpController;。漏掉末尾的反斜杠、多写一个 \、路径大小写不一致(尤其在 Linux/macOS 上),都会导致类找不到。
-
"App\"是必须带结尾反斜杠的字符串,"App"或"App\"(多一个)都是无效的 - 目录名
src/必须真实存在,且不能是软链接或未提交的空目录(Composer 不报错,但dump-autoload后仍无法加载) - Windows 下路径分隔符用正斜杠
/即可,Composer 内部会自动适配
composer dump-autoload 不是“自动触发”的
修改 composer.json 中的 "autoload" 后,Composer 不会实时重载规则。你得手动运行:
composer dump-autoload
如果加了 -o(optimize)参数,它会生成静态映射表,跳过文件扫描,速度更快但更敏感——此时若新增类文件但没重新 dump,就会报 Class not found。
- 开发阶段建议只用
composer dump-autoload,不用-o - CI/CD 或生产部署时再加
-o,并确保该步骤在代码复制完成后执行 - 运行后检查
vendor/composer/autoload_psr4.php是否已更新,这是最直接的验证方式
多个 PSR-4 根路径可以共存,但不能重叠
你可以为不同命名空间指定不同源目录,例如:
"autoload": {
"psr-4": {
"App\": "src/",
"Tests\": "tests/",
"Vendor\Package\": "packages/my-package/src/"
}
}
但要注意:"App\Admin\" 和 "App\" 没问题;而 "App\Helper\" 和 "App\Helper\Utils\" 这种嵌套式前缀不会报错,但后者永远无法命中——因为 "App\Helper\" 已先匹配到 src/Helper/ 目录,Composer 不会继续往下找更长的前缀。
- 前缀顺序无关紧要,Composer 内部按长度降序匹配,所以长前缀优先
- 不要用
"\"(根命名空间)做 PSR-4 映射,它不被支持;要用"": "lib/"这种空字符串方式(属于 PSR-0 兼容写法,非 PSR-4) - 测试类推荐单独用
"autoload-dev"块配置,避免污染主 autoload
最常被忽略的是命名空间声明与文件路径的**双向一致性**:改了 namespace 必须同步调路径,改了目录结构必须同步调命名空间,二者缺一不可。Composer 只负责“查表”,表错了,它就只能返回 Class not found。


















