答案是运行composer why-not vendor/package:version定位阻塞链,它逐层展开require、require-dev及间接依赖中的互斥约束,首行包即最上游封杀者;若输出为空则可能版本号错误或minimum-stability限制所致。

composer why-not 能直接定位阻塞源头
“负载调度”不是 Composer 的术语,依赖冲突里不存在调度概念——它本质是 SAT 求解器在版本约束图中找不出满足所有条件的解。真正该用的命令是 composer why-not,它从你想要安装的包版本出发,逆向推导谁锁死了路径。
常见错误是误用 composer depends:它只列出“谁依赖这个包”,但不带版本限制,完全无法判断为什么 monolog/monolog:2.9.0 装不上。
- 运行
composer why-not vendor/package:version(例如composer why-not monolog/monolog:2.9.0) - 输出第一行通常是
Root package requires "php": "^7.4"或类似手动写死的窄约束 - 如果阻塞源是某个中间包(比如
spatie/laravel-backup),先查它的 Packagist 页面,确认是否已发布支持目标版本的 release - 避免在 CI/CD 中跳过平台检查:
--ignore-platform-reqs会让vendor/里混入 PHP 8.1 语法,本地php -l就报ParseError
composer update 必须定点 + 带依赖链
默认 composer update 会重算整棵树,极易把 guzzlehttp/guzzle 从 7.x 升到 8.x,导致 new GuzzleHttp\Client() 直接报错。这不是升级,是破坏性变更。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 只更新指定包:
composer update monolog/monolog(不加引号、不加^) - 加上
--with-dependencies:只允许升该包及其直系依赖,不碰phpunit这类无关项 - 加
--dry-run预览:composer update monolog/monolog --with-dependencies --dry-run - 执行后立刻
git diff composer.lock,只接受预期变更;如果改动十几个包,说明约束没控住,得回退
composer.lock 合并冲突不能手动改
Git 合并时出现 标记的 <code>composer.lock,千万别手删标记、填版本号或瞎改哈希值。Composer 不认这种“人工修复”,后续 install 会校验失败。
- 保留你当前分支的
composer.json(即已确认可用的依赖声明) - 运行
composer update --lock:它会重新解析依赖图、生成合法哈希、清除冲突标记 - 若提示 “Your lock file does not contain require-dev information”,说明 dev 依赖没同步,补上
--with-all-dependencies - 生成后立刻
git add composer.lock并提交,别等下次 install 再暴露问题
PHP 版本不匹配不是配置问题,是运行时环境错位
报错 requires php ^8.1 but your PHP version (7.4.33) does not satisfy that requirement,根源不是 composer.json 写错了,而是当前 shell 调用的 php 命令版本不对。
- Linux/macOS 下明确调用目标二进制:
/usr/bin/php8.1 composer install - Windows 下用完整路径:
"C:\php\php81\php.exe" composer install -
config platform.php是个陷阱:它只应在打包部署场景用(如 PHP 7.4 机器上生成适配 PHP 8.2 的vendor),且必须配合--ignore-platform-reqs使用,日常开发禁用
真正卡点往往藏在最上面一行 why-not 输出里,或是 composer.lock 被合并工具糊掉的哈希值。这些地方不细看,花半天时间硬调版本约束也没用。










