Composer path仓库require失败主因是name或路径不匹配:name须与require逐字一致(大小写、仅短横线),路径须为相对主项目composer.json的合法目录;symlink失效因本地包composer.json缺"options": {"symlink": true};autoload需主项目显式配置或验证dump-autoload是否识别;循环依赖需composer depends --tree实锤,require-dev中跨目录autoload是隐式闭环高发区。

path仓库配置后require失败,90%是name或路径不匹配
Composer不会模糊匹配包名或路径,name字段必须和require中写的**逐字一致**:大小写、分隔符(仅允许短横线-,不能用下划线_或驼峰)、vendor名全部对齐。路径也一样——url指向的是含composer.json的目录,且必须是相对于主项目composer.json的位置(如"../my-pkg"),不能是 shell 当前工作目录下的相对路径。
常见错误现象:Could not find package vendor/name,但composer show --all里根本没出现该包名。
- 检查本地包根目录下是否存在合法
composer.json(无尾逗号、全双引号、JSON语法有效) - 确认
name字段值与require中字符串完全相同,例如"acme/utils"≠"Acme/utils" -
url末尾不要加/,"../my-pkg/"会导致Composer静默忽略整个仓库 - Windows用户避免路径含中文或空格,某些PHP版本解析会失败
为什么改了代码没生效?symlink没启用或fallback了
path类型仓库默认尝试创建符号链接,但失败时会静默回退到复制(copy)模式。结果是你改本地源码,vendor/里还是旧副本——这是最隐蔽的调试陷阱。
关键不在主项目composer.json里配"symlink": true,而在于**本地包自己的composer.json中是否声明了"options": {"symlink": true}**。缺这句,Windows上即使管理员权限运行终端,也会fallback;Docker容器挂载宿主机目录时也常因权限丢失symlink能力。
- 验证是否真用了symlink:
ls -la vendor/vendor/name(Linux/macOS)或dir vendorendor ame(Windows),看到->或JUNCTION才是成功 - 如果显示为普通文件夹,说明已fallback成copy,立刻检查本地包
composer.json是否漏了options段 - Windows下必须以管理员身份运行终端,否则symlink创建失败且无提示
- Docker场景需在
docker run时加--cap-add=SYS_ADMIN,并确保挂载方式支持符号链接(如-v $(pwd)/../my-pkg:/workspace/my-pkg不行,得用绑定挂载并透传宿主机权限)
autoload不生效,不是Composer没加载,而是映射没更新
path仓库让包“存在”,但类能否被new或use,取决于autoload映射是否包含它的真实路径。即使本地包composer.json写了"psr-4": {"Acme": "src/"},主项目也不会自动继承这个autoload配置。
你必须手动在主项目的composer.json中显式声明对该命名空间的映射,或确保本地包的autoload配置已被dump-autoload识别并写入vendor/composer/autoload_psr4.php。
- 运行
composer dump-autoload -v,观察输出里是否扫描到了你的命名空间(如Acme) - 若压根没出现,说明autoload配置根本没被识别——检查
composer.json是否有语法错误(多逗号、BOM、单引号)、PSR-4键值末尾是否漏了反斜杠("Acme\"✅ vs"Acme"❌) - 若扫描到了但跳过了某些文件,注意看提示:可能是文件含BOM、短标签未启用、或存在
.php.bak这类非法PHP文件卡住解析 - 最终映射是否写进
vendor/composer/autoload_psr4.php?打开它搜索你的前缀,确认映射路径是绝对路径(如$baseDir . '/src'),再手动检查该路径下是否存在对应文件
循环依赖不是“深度递归调用”,而是SAT求解器无限回溯
Composer遇到循环依赖直接拒绝解析,本质是SAT求解器在闭环中无限回溯,表现为CPU持续95%+、内存飙升、终端卡住后退出;它不会尝试解开,也不会报“栈溢出”,而是静默卡死几十秒后突然退出。
真正能实锤闭环的命令只有composer depends --tree,但它有两个硬前提:项目已有有效的composer.lock,且命令必须带--tree参数。否则只显示一级依赖,完全漏掉间接环。
- 运行
composer depends myorg/core --tree,若输出含myorg/core ← myorg/api ← myorg/core,箭头方向是“被谁依赖”,自身出现两次即闭环成立 - 若报
Package not found,说明该包根本没进composer.lock——先删vendor/和composer.lock,再跑composer update --dry-run -v看第一步失败点 - 别只查
composer depends myorg/core(无--tree),那只是上游快照,看不出链路折叠 -
require-dev中的autoload是80%隐式循环的源头:比如phpunit/phpunit的"autoload": {"psr-4": {"App\": "../src/"}}就会让它加载你的src/,等于把你的代码反向拉进了它的运行时上下文
实际排查时最容易被忽略的点是:**本地包自己的composer.json里没配"options": {"symlink": true},以及require-dev里那些跨目录autoload的测试工具——它们不声不响就把你的代码变成了自己的依赖,形成隐式闭环。**











