本地包自动加载需三步闭环:主项目配置path仓库、本地包自身composer.json声明autoload、主项目执行dump-autoload;缺一不可,否则类找不到。

本地包的 autoload 必须在包自身 composer.json 中声明
主项目的 autoload 配置对本地包完全无效。Composer 加载类时,只读取被 require 的包自己 composer.json 里的 autoload 段。常见错误是只在主项目里配了 PSR-4,却忘了给本地包加——结果 composer install 成功,但类始终 Class not found。
本地包根目录下必须有合法的 composer.json,且含:
-
"name"字段(如"acme/my-utils"),需与主项目require中的包名完全一致 -
"autoload"字段,例如:{ "autoload": { "psr-4": { "Acme\Utils\": "src/" } } } - 命名空间末尾双反斜杠
\不可省略,路径用正斜杠结尾("src/"),大小写与文件系统严格一致 - 路径是相对于该本地包根目录的,不是主项目根目录:别写成
"src/Acme/Utils/"
主项目必须通过 path 仓库显式引入本地包
repositories 必须写在主项目 composer.json 的顶层,不能嵌套在 autoload 或其他字段里。格式必须是数组,且 url 用相对路径:
- 正确:
"url": "./packages/my-utils" - 错误:
"url": "file://./packages/my-utils"、"url": "~/packages/my-utils"、"url": ".\packages\my-utils"
目标目录(如 ./packages/my-utils)下必须已执行 git init 并至少有一个 commit,否则 Composer 拒绝加载;同时该目录必须有合法 composer.json,含可识别版本(如 "dev-main")。
require 必须用 dev-分支名,且需手动 dump-autoload
主项目 require 中不能写版本号或通配符,必须显式指定当前 Git 分支名:
- 正确:
"acme/my-utils": "dev-main"(大小写必须与实际分支名完全一致) - 错误:
"acme/my-utils": "^1.0"、"acme/my-utils": "*"、"dev-main as 1.0"
改完本地包的 autoload 或主项目 repositories/require 后,必须运行:
-
composer dump-autoload(刷新主项目和已安装包的自动加载映射) - 验证是否生效:打开
vendor/composer/autoload_psr4.php,搜索你的命名空间前缀(如"Acme\Utils\"),确认存在对应路径
如果本地包切了分支(比如从 main 切到 develop),require 也必须同步改成 "dev-develop",否则仍加载旧分支代码。
为什么 vendor/autoload.php 存在却 still Class not found
最常被忽略的是三步闭环缺一环:path 仓库配置 ✅ + 本地包自身 autoload ✅ + 主项目 composer dump-autoload ✅。少任何一步,autoload_psr4.php 就不会写入你的映射。
另一个隐蔽点:本地包目录若没 git init 或没 commit,Composer 会静默跳过该包(不报错),导致 require 看似成功,实则根本没装进去。此时 composer show acme/my-utils 会返回 “Package not found”,但很多人没查这步就直接调试类加载了。


















