本地包配置失败主因是name或路径不匹配:repositories需声明type为path且url指向含合法composer.json的目录;本地包composer.json的name必须与require中逐字一致;PSR-4映射、文件路径、命名空间须严丝合缝;符号链接需本地包自身配置options.symlink;autoload变更后须手动dump-autoload。

本地包配置失败,90% 是 name 或路径不匹配,不是 Composer 坏了,也不是网络问题。
为什么 composer install 找不到本地包
根本不是“没扫描到”,而是三个硬性条件缺一不可:
- 主项目
composer.json的repositories段必须显式声明"type": "path",且url指向**含合法composer.json的目录**(不能是文件,不能带末尾/) - 本地包根目录下必须存在语法正确的
composer.json(无尾逗号、全双引号、JSON 有效) - 该
composer.json中的name字段必须和主项目require里写的**逐字一致**:大小写、分隔符(只允许短横线-)、vendor 名全部对齐,acme/utils≠Acme/utils
常见错觉:“路径我写了 ../my-pkg,明明就在那儿”。但若当前终端工作目录不是主项目根目录,或路径用了 ~/my-pkg(Composer 不解析 ~),或本地包 composer.json 里 name 是 acme/my-utils 而你 require 了 acme/myutils,都会静默跳过整个仓库。
Class not found 真因不是包没装,而是 PSR-4 映射断了
即使 composer show 能列出本地包,new MyPackageHttpClient() 仍报错,说明自动加载没通——PSR-4 配置、文件路径、命名空间三者必须严丝合缝:
-
composer.json中"psr-4": {"MyPackage\": "src/"}→ 要求所有类在src/下,且命名空间以MyPackage开头 - 文件
src/Http/Client.php必须真实存在,且顶部写namespace MyPackageHttp;(注意Http大写、无多余反斜杠) - 目录名必须和命名空间子段完全一致:
src/http/Client.php+namespace MyPackageHttp;就会失败(http ≠ Http) - 如果本地包和主项目都映射了
"App\": "src/",后加载的规则会覆盖前一个,导致类被静默替换
验证方法:运行 composer dump-autoload -p,搜索你的命名空间前缀,看它到底指向哪个物理路径。
改了代码没生效?大概率 symlink fallback 了
Path 仓库默认尝试符号链接,但失败时会静默回退到复制模式。你改本地源码,vendor/ 里还是旧副本——这是最隐蔽的坑。
- 关键不在主项目配
"symlink": true,而在**本地包自己的composer.json是否有"options": {"symlink": true}** - Windows 下必须以管理员身份运行终端;Docker 需加
--cap-add=SYS_ADMIN并确认挂载支持 symlink - 验证是否真用了 symlink:
ls -la vendor/vendor/name(Linux/macOS)看到箭头,或dir vendorendor ame(Windows)看到JUNCTION才算成功
如果显示为普通文件夹,立刻检查本地包 composer.json 的 options 段是否遗漏,别在主项目里瞎配。
autoload 更新不及时,缓存不会自动感知变更
你手动改了 src/Client.php 里的 namespace 行,或者调整了 psr-4 映射,Composer 的自动加载器不会自动重生成规则。
- 必须手动执行
composer dump-autoload -o(-o表示优化,生成静态映射) - 如果本地包加了测试类并误塞进
autoload.psr-4(比如"Acme\": ["src/", "tests/"]),会导致和主项目同名测试类冲突;应改用autoload-dev.psr-4 - 改了命名空间后还报
Cannot declare class X, because the name is already in use,基本就是旧映射还在缓存里,清完再dump-autoload
真正麻烦的从来不是“怎么配”,而是“配完之后谁在管路径映射、谁在管符号链接、谁在管 autoload 缓存”——这三个环节任何一个断掉,错误都静默发生,且现象高度相似。











