composer update --lock 在 composer 2.2+ 中仅重写 lock 文件元数据(如 content-hash、platform 字段),不重算依赖、不校验版本变更、不检查 vendor 一致性,前提是 composer.json 依赖声明未改动且已安装包仍满足约束;它忽略 require 版本变更、不报错、不同步,易导致锁文件与声明不一致。

composer update --lock 不是“只改 lock 不动 vendor”的万能开关,它在不同 Composer 版本中行为不一致,且极易被误用——你看到的“没装包”,可能只是运气好,不是设计如此。
composer update --lock 在 Composer 2.2+ 中到底干了什么
它不再重算依赖树,也不下载包,但会强制重写 composer.lock 文件,仅刷新元数据字段(如 content-hash、platform、platform-check),前提是:composer.json 没改过依赖声明,且本地 vendor/ 中已安装的包仍满足所有约束。
- 如果只改了
config.platform.php或加了repositories,它会更新 lock 中对应字段,不碰包版本 - 如果
composer.json里require的版本号变了(比如"monolog/monolog": "^2.0"→"^3.0"),它完全忽略 —— lock 文件里还是旧版本,不会报错也不会同步 - 输出只有
Writing lock file,没有其他提示,容易让人误以为“已生效” - 它不校验
vendor/内容是否与 lock 中的dist.sha256一致,哪怕本地文件被手动删改,也照写不误
为什么 composer update --dry-run 不能用,但 --lock 又靠不住
composer update --dry-run 是非法命令,Composer 直接报错:Unrecognized option: --dry-run。而 composer update --lock 虽然合法,却无法响应 composer.json 的真实变更。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 你想预览“把 PHP 升到 8.3 后哪些包会变”?
--lock不行,它只看当前 vendor 状态,不重新解析约束 - 你想确认
"phpunit/phpunit": "^10.0"改成"^11.0"后有没有冲突?--lock静默跳过,composer update --dry-run根本不存在 - 唯一能真正模拟变更影响的,是
composer update --dry-run的替代方案:先跑composer update --no-install(需 Composer 2.5+),再git checkout -- composer.lock回滚 —— 但这不是标准流程,CI 中难落地
真正安全的“只更新 lock”操作其实不存在
Composer 没有官方支持的纯元数据写入命令。所谓“只改 lock”,本质是在赌:当前 vendor/ 和 composer.json 仍兼容。一旦不兼容,--lock 就会产出一个语义错误的 lock 文件。
- CI 中想验证 lock 合法性?用
composer validate --strict+composer install --no-scripts --no-plugins更可靠 - 合并分支后发现 lock 和 json 不一致?别信
--lock,直接composer update并提交新 lock - 只想刷新 content-hash(比如 PHP 版本变了)?
composer install是更稳妥的选择:它读 lock、校验哈希、只重写不匹配的 dist 字段,不升级包 - 手动编辑
composer.lock?绝对禁止。content-hash依赖composer.json的**字节级内容**(含空格和注释),微小改动就会让后续所有命令失败
最常被忽略的一点:composer update --lock 在 Composer 2.2+ 默认输出 v2 格式 lock 文件,而某些老旧私有仓库插件或自定义 CI 脚本只认 v1。一次看似无害的执行,可能让整个部署链路静默中断。










