composer why-not 是唯一能定位冲突源头的命令,它不依赖缓存或lock文件,直接从约束条件逆向推导阻塞包;报错“conclusion: don’t install”时应立即运行该命令,且必须指定完整语义版本号(如1.2.3),输出最上方通常为root package requires,揭示composer.json中过窄的手动约束。

composer why-not 是唯一能定位冲突源头的命令
它不依赖缓存或 lock 文件,直接从约束条件逆向推导谁在阻止某个版本安装。报错里出现 Conclusion: don't install vendor/package:1.2.3 时,别看错误文字本身,立刻运行 composer why-not vendor/package:1.2.3。
常见误操作包括:
- 用
composer depends替代 —— 它只告诉你“谁用了这个包”,不体现版本限制,无法诊断冲突 - 写成
composer why-not vendor/package:^1.2或1.2—— 必须带完整语义版本号,如1.2.3,否则可能匹配不到元数据 - 镜像未生效或缓存未清 ——
composer why-not输出为空,不等于没冲突,而是元数据根本没加载到对应版本的conflict规则
输出最上面一行通常是 Root package requires,说明是你 composer.json 里手动写的约束太窄(比如 "php": "7.4"),下面几行则是中间包层层锁死的路径。
composer update --dry-run -v 看清 SAT 求解卡在哪
当终端停在 Resolving dependencies through SAT、CPU 占满、无网络请求时,不是网络慢,是本地穷举组合失败。加 --dry-run -v 能暴露求解器的真实行为。
关键线索有:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 反复出现同一组包来回尝试(如
monolog/monolog 2.x → spatie/laravel-backup 7.0 → laravel/framework 10.x,然后退回试monolog 3.x)——大概率是某处conflict字段在硬拦 - 大量
php >=7.4组合被枚举 —— 平台约束太宽,收紧为"php": "^8.1"可减少 80%+ 求解时间 - 频繁出现
dev-main或dev-develop—— 检查私有包是否悄悄升级了依赖要求(如新增了"guzzlehttp/guzzle": "^7.8")
镜像配置不生效是 90% 的“换源无效”根源
Composer 静默 fallback 回 packagist.org,你根本不知道镜像没起作用。验证是否生效必须三步齐做:
- 运行
composer config -g repo.packagist,输出应为完整 URL 字符串(如https://mirrors.aliyun.com/composer/),不是null或空 - URL 必须以
/结尾,少斜杠会拼出https://mirrors.aliyun.com/composerpackages.json,404 后直接降级 - 命令末尾必须带
composer类型标识:composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/,漏掉composer会被当普通 URL 处理
另外,只要项目 composer.json 里存在 "repositories" 字段(哪怕空数组),全局镜像就会被彻底忽略 —— 不是合并,是丢弃。
require-dev 包也会参与依赖解析并引发冲突
很多人以为 composer install 只装 require,其实 require-dev 中的包同样参与 SAT 求解,尤其当它们自带宽松 PHP 版本要求(如 phpunit/phpunit 要求 ^8.0)时,会把整个树拖向高版本。
排查建议:
- 临时注释掉所有
require-dev条目,再跑composer update --dry-run,如果不再卡住,问题就在这里 - 检查
require-dev包的autoload配置,特别留意含../或src/的路径 —— 这类配置可能引入隐式循环依赖 - 不要在
autoload-dev里把vendor/下的路径写进去,等于告诉 Composer:“我依赖我自己”
真正棘手的冲突往往藏在 require-dev 和 autoload 的交界处,而不是主依赖列表里。










