composer install 严格遵循 composer.lock 文件安装确定版本,确保环境一致;composer update 忽略 lock 文件,重新解析 composer.json 并更新依赖,可能引入不兼容变更。

composer install 和 composer update 的核心区别就一条:是否读取并遵守 composer.lock 文件。前者只读 lock,确保复现;后者完全忽略 lock,强制重算依赖——用错一个字,线上就可能出问题。
composer install:只读 composer.lock,不碰 composer.json 的约束
它不是“安装最新兼容版”,而是“照着锁文件一模一样装”。只要 composer.lock 存在,composer install 就不会去解析 composer.json 里的 ^2.1 或 dev-main 这类模糊约束。
- 有
composer.lock→ 直接按里面记录的完整版本号、哈希值、源地址批量下载解压,跳过依赖求解器,快且确定 - 没有
composer.lock→ 退化为首次初始化:读composer.json,求解依赖,生成新composer.lock - 从不修改
composer.lock,哪怕你改了composer.json也不管 - CI/CD 流水线、生产服务器部署、新人克隆项目后第一件事,都该跑它
composer update:主动丢掉 composer.lock,重新跑依赖求解器
它不是“更新已装包”,而是“根据 composer.json 当前所有约束,联网查、CPU 算、重新挑一套满足条件的最新组合”。结果必然覆盖 composer.lock。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 不管 lock 里写的是什么,一律重新解析
composer.json中的require和require-dev - 会触发完整的依赖图遍历 + 版本冲突检测 + 回溯求解,耗时长、网络请求多
- 可能升级次要版本(如
3.2.1 → 3.3.0)甚至主版本(如果约束写得宽,比如*或^2.0 || ^3.0),带来不兼容风险 - 支持精准控制范围:
composer update monolog/monolog或composer update "phpunit/*",避免全量升级
常见踩坑场景和应对
很多问题其实不是命令本身的问题,而是没理解 lock 文件的协作意义。
- 本地
composer install装出来的 vendor 和 CI 上不一样?→ 检查composer.lock是否被 gitignore 了,或没提交 - 执行
composer update后功能异常?→ 不是 update 本身错,而是你没在测试环境验证新依赖组合,也没看 changelog - 想加一个新包但不想动其他依赖?→ 别用
update,用composer require vendor/package:version,它会智能合并进 lock - 生产环境误跑了
composer update?→ 立即git checkout composer.lock && composer install回滚,别试图“修复”
什么时候必须用哪个命令
判断依据只有一个:你要的是“稳定复现”,还是“主动变更”。
- 克隆项目、部署上线、CI 构建 →
composer install --no-dev(加--no-dev是常规操作,不是可选项) - 修复安全漏洞(如
symfony/http-foundationCVE)、接入新 API、替换废弃包 →composer update vendor/package,验证后提交新composer.lock - 只是加个调试工具或日志组件?→
composer require --dev phpunit/phpunit,它比手动改 json + update 更安全
最容易被忽略的一点:lock 文件不是“缓存”,它是契约。一旦团队不提交它,install 就失去意义;一旦你在生产机上手欠跑 update,契约就当场作废。

















