psr-4自动加载完全取决于本地composer.json的顶层autoload配置、严格匹配的命名空间与路径结构(含大小写)、以及必须执行的composer dump-autoload命令,与仓库公私属性无关。

私有仓库的 PSR-4 自动加载,和公开包完全一样——它不看仓库地址,只看你本地 composer.json 里怎么配、文件结构是否对得上、有没有跑 composer dump-autoload。
composer.json 的 autoload 必须写在顶层,不能藏在 require 或 scripts 里
私有包哪怕通过 repositories 指向 GitLab 或自建 Satis,它的自动加载规则仍由该包自己的 composer.json 决定。但关键点是:你项目根目录下的 composer.json 里,autoload 字段必须是和 name、require 并列的一级键,拼写必须是 "autoload"(不能是 autoloader、autoloads 或带连字符)。
- 错误写法:
"require": { "my/private-package": "*" }, "autoloader": { "psr-4": { "My\": "src/" } }→ Composer 完全忽略 - 正确位置:
{ "name": "...", "require": {...}, "autoload": { "psr-4": { "My\": "src/" } } } - 如果你用的是私有包(比如
my/private-package),它的autoload配置应写在它自己源码根目录的composer.json中,不是你的主项目里
命名空间结尾必须是双反斜杠,路径必须是相对正斜杠结尾
PSR-4 匹配靠字符串前缀,不是模糊识别。"My": "src/" 表示:所有以 My 开头的类,都从 src/ 目录下找;而 "My": "src/" 在 JSON 中会被解析为不带反斜杠的字符串,匹配失败。
- 命名空间声明必须带双反斜杠结尾:
namespace MyHttpControllers;✅,namespace MyHttpControllers❌(少分号不算,但结尾缺就不行) - 路径值不能以
/开头(如"/src/"),也不能含../或绝对路径;推荐加尾部斜杠:"src/"✅,"src"❌(否则可能拼出srcMyClass.php) - Linux/macOS 下大小写敏感:
src/Http/Controllers/HomeController.php和src/http/controllers/homecontroller.php是两个不同文件
改完配置后必须手动运行 composer dump-autoload
vendor/autoload.php 只是入口,真正干活的是 vendor/composer/autoload_psr4.php —— 这个文件不会自动更新,也不会报错提醒你配错了。你不跑命令,它就永远用旧映射。
- 开发时用
composer dump-autoload(不加-o),能暴露路径拼接错误,比如提示 “tried loading src/Http/Controllers/HomeController.php but file not found” - 部署时用
composer dump-autoload -o或composer install --optimize-autoloader --no-dev,但前提是路径已验证无误;否则 classmap 模式只会静默报Class not found,连尝试路径都不显示 -
composer install或update不会重新生成 autoload 文件,除非锁文件变更或显式加--dump-autoload
私有包中 PSR-4 映射与主项目冲突怎么办
多个 PSR-4 映射共存时,Composer 按 autoload_psr4.php 数组顺序查找,先匹配上的就用哪个。如果私有包和主项目都声明了 "App\": "src/",后者会覆盖前者(因为主项目的配置写在顶层,优先被写入 autoload_psr4.php)。
- 避免前缀重叠:私有包用
"MyVendor\Package\": "src/",主项目用"App\": "app/" - 检查最终映射:
var_dump(include 'vendor/composer/autoload_psr4.php');确认数组里有没有你要的键值对 - 若私有包依赖其他私有包,确保每个包的
composer.json都正确声明了自己的autoload,且没有漏掉composer dump-autoload步骤
最常被忽略的其实是路径大小写和命名空间声明行末尾空格——它们在 Windows 上可能“看起来正常”,一上 Linux 就直接 Class not found,连报错路径都不会给你显示。











