composer update –lock 仅同步 composer.lock 与 composer.json 及本地 vendor 包版本,不安装/删除包、不联网、不校验内容完整性;适用于 php 版本更新、ci 环境锁文件保鲜等场景。

它根本不会更新任何包,只重写 composer.lock 文件 —— 但前提是你的 composer.json 没变,且本地已有的依赖能完全满足约束。
为什么 composer update --lock 不装包也不删包
这个命令的唯一目标是让 composer.lock 和当前 composer.json 声明的版本约束、平台配置(PHP 版本、扩展)、以及你本地 vendor/ 里**实际已安装的包版本**三者对齐。它不联网、不读 packagist、不执行 install 或 update 的解包逻辑。
常见错误现象:composer update --lock 后 composer.lock 时间戳变了,但 vendor/ 里文件没动,git status 只显示 lock 文件变更 —— 这是完全正常的,说明它成功完成了“轻量同步”。
- 如果你改过
composer.json(比如调了 PHP 版本或加了platform配置),--lock会按新约束重新生成 lock 中的哈希和 platform 字段 - 如果本地
vendor/缺包、或多出未声明的包,它不会帮你清理 —— 那属于composer install或手动rm -rf vendor的职责 - 它不校验包内容完整性(比如 tarball hash),只确保 lock 文件结构合法、可被后续
install消费
composer update --lock 的典型使用场景
不是日常开发操作,而是用于特定协作或 CI 环境下的“锁文件保鲜”。
- 团队升级了 PHP 版本,所有人要统一 lock 文件中的
platform字段,但不想触发全量依赖重解析 - CI 流水线中,先
composer install装包,再跑测试;测试完想把当前环境的真实 platform 信息写进 lock,供下次构建复用 —— 此时用--lock比update快且确定 - 你手动编辑过
composer.json的require版本号(比如从"monolog/monolog": "^2.0"改成"^3.0"),但还没运行update,只想先生成一个语法合法、字段齐全的 lock 文件占位(注意:此时 lock 中的版本仍为旧版,真正升级要等后续update)
容易踩的坑:它不解决版本冲突,也不修复损坏的 lock
很多人以为加了 --lock 就更“安全”,其实它对 lock 文件本身的语义错误无感。
- 如果 lock 文件里某个包的
dist.sha256校验和与本地vendor/实际内容不一致,--lock完全不管 —— 它只读 lock,不读 vendor 内容 - 如果
composer.json里写了非法约束(比如"php": ">=8.1 ),<code>--lock会直接报错退出,而不是静默忽略 - 它不会自动降级或升級包来满足新约束 —— 比如你把 PHP 版本从 8.0 改成 8.3,而当前 lock 里有个包声明
"php": "^8.0 || ^8.1",那--lock会失败,提示无法满足 platform 要求
替代方案对比:什么情况下不该用 --lock
当你要确保 lock 和 vendor 严格一致,或者 lock 文件本身已经偏离预期,--lock 就不是正确工具。
- 想验证当前
vendor/是否真能由 lock 文件重建?用composer install --dry-run - 怀疑 lock 文件被手改坏、或和
composer.json不匹配?直接composer update --lock+composer install --dry-run连用,看第二步是否报错 - 只是想更新某几个包,又不想动其余依赖?别用
--lock,老实用composer update vendor/package
真正需要 --lock 的时刻很少,但它在自动化流程里是个安静的校准器 —— 用对了省时间,用错了连问题在哪都难定位。