“Your requirements could not be resolved”是依赖冲突,非网络或权限问题;本质是Composer本地穷举后无法找到满足全部约束的版本组合,需用composer update --dry-run -v定位冲突源头。

“Your requirements could not be resolved” 不是网络或权限问题,而是 Composer 在本地穷举所有版本组合后,确认没有任何一组能同时满足你当前全部约束——删 composer.lock 或清缓存基本没用,得让它把“谁和谁打起来了”摊开给你看。
运行 composer update --dry-run -v 看冲突源头
这个命令不改任何文件,但会完整走一遍依赖求解流程,并在输出末尾明确写出逻辑矛盾。关键信息藏在最后 10 行:
- 盯住
Because package-a v2.1 requires symfony/console ^5.4, and package-b v3.0 requires symfony/console ^6.0这类句式——它直接告诉你哪两个包在互斥 - 反复出现的包名(如
monolog/monolog、guzzlehttp/guzzle)大概率是冲突枢纽,优先查它们 - 别跳过
Root requirements段落,它指出是你composer.json里哪一行(比如"laravel/framework": "^10.0")触发了整条链崩塌
用 composer why-not 和 composer prohibits 反向定位拦路虎
光知道“装不上”不够,得搞清“谁不准你装”和“谁被你挡了路”:
-
composer why-not laravel/framework:11.0→ 查哪个已装包硬性排斥该版本(比如spatie/laravel-backup的"conflict": {"laravel/framework": ">=11"}) -
composer prohibits monolog/monolog:^2.0→ 查当前项目里哪些包强制锁定了旧版(如^1.25),从而把 2.x 挡在外面 - 注意:必须写全包名+版本号,只输
monolog会报[InvalidArgumentException] Package not found
检查 require-dev 是否拖后腿
很多调试工具(如 phpunit/phpunit、larastan/larastan)被错误地塞进 require,实际它们只该在 require-dev 里——但只要在 composer.json 中声明了,就参与全局依赖解析:
- 先试
composer update --no-dev --dry-run -v:如果这时成功了,说明冲突源就在 dev 工具链 - 再单独查可疑包:
composer show phpunit/phpunit看它支持的 PHP 版本;composer show phpunit/phpunit 9.6.0看该版本具体 require 了什么 - 记住:
require-dev不该影响生产环境行为,但它真会影响依赖解析结果
确认 PHP 版本和扩展是否被隐式卡住
PHP 版本本身是隐式依赖,而 ext-xxx 扩展要求常被忽略:
-
composer why-not php:8.3→ 查哪个包锁死了低版本(比如老 bundle 写了"php": "7.4.0") - 报错里带
ext-pcntl或ext-dom?那是某个包(如laravel/horizon)要求 CLI 模式下启用对应扩展,但你的php -m里没列出来 - 临时绕过可用
--ignore-platform-reqs,但仅限调试——装完可能运行时报错,不能进 CI
真正难处理的不是报错本身,而是多个约束交叉作用时产生的间接冲突:比如 A 包没写 conflict,但它依赖的 B 包写了;或者你没动 composer.json,但上游某个包悄悄改了 conflict 字段。这时候 --dry-run -v 输出里的 “because… and because…” 链式推理,就是唯一可信的线索。











