composer install 从不解析命令行版本参数,只严格按 composer.lock 还原精确版本;想换版本必须先改 composer.json 或用 composer require 更新 lock 文件。

composer install 从不解析命令行里的版本号
它只认 composer.lock,完全忽略你输的任何版本参数。比如 composer install monolog/monolog:1.2.3,install 会直接扔掉冒号后内容,甚至报 Unknown argument。这不是 bug,是设计如此——install 的唯一职责是“还原”,不是“选择”。
想换版本?必须先改 composer.json(比如把 "monolog/monolog": "^2.0" 改成 "monolog/monolog": "1.2.3"),再跑 composer install;或者用 composer require monolog/monolog:1.2.3,它会自动更新 composer.json 和 composer.lock。
版本范围在 install 阶段已冻结,只读 lock 文件
composer install 启动时,第一件事是检查是否存在 composer.lock。如果存在,它就跳过所有版本约束解析逻辑,直接按 lock 文件里记录的 version、dist.reference、source.type 去下载——哪怕 composer.json 里写的是 ~1.2,lock 里存的是 1.2.4,它就装 1.2.4,不多问也不升级。
常见误解是“改了 json 里的版本范围,run install 就能生效”。错:只有删掉 composer.lock 再 install,才会重新走依赖解析;否则所有范围符号(^、~、>=)都只是历史快照,对本次 install 没影响。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
为什么 lock 文件里的 version 字段可能和你预期不符
你以为锁的是 "version": "1.2.3",结果 vendor 里却是 dev 分支代码,大概率是以下任一情况:
-
composer.lock中该包条目的source.type是"source"而非"dist" -
source.reference是一个长 commit hash(如"a1b2c3d4e5f67890..."),说明拉的是 git commit,不是 tag - 你在
require时用了分支别名(如dev-main)或带哈希的写法(dev-main#abc123),而没加--prefer-dist
验证方式很简单:cat composer.lock | jq '.packages[] | select(.name=="monolog/monolog")',重点看 version、source.type、source.reference 这三字段。
platform 配置不影响 install 的版本选择,只影响依赖可解性
"platform": {"php": "8.1.0"} 这类配置,只在 composer install 前的依赖解析阶段起作用——它告诉 Composer:“假装当前 PHP 是 8.1”,从而让那些声明 "php": "^8.1" 的包能通过校验。但它不改变实际下载哪个版本,也不干预 composer.lock 里已锁定的 version 字段。
真正危险的是 runtime 环境和 platform 不匹配:比如 lock 里装了只兼容 PHP 8.1 的 ext-xml 扩展,但你用 PHP 7.4 运行,install 成功了,autoload 或运行时直接 fatal error。所以 platform 是“解析开关”,不是“运行环境代理”。
composer.lock 里那几行 JSON。删 lock、改 json、再 install —— 这三步才是可控路径。任何试图绕过 lock 直接“指定版本 install”的操作,都会撞上设计边界。










