composer install 严格依据 composer.lock 文件安装依赖,确保环境一致性;若修改 composer.json 后未更新 lock 文件并提交,会导致本地与 CI 环境不一致。

composer install 读的是 composer.lock,不是 composer.json
很多人以为 composer install 是根据 composer.json 装包,其实它优先检查是否存在 composer.lock;有就严格按锁文件装,连版本号、commit hash、dist url 都一模一样。这是为了保证多人协作或部署时环境一致。
常见错误现象:
• 本地改了 composer.json 增加一个包,运行 composer install 却没装上
• CI 环境里依赖行为和本地不一致,查半天发现是有人忘了提交 composer.lock
- 如果想让
composer.install忽略锁文件(极少见),加--no-lock参数,但会失去确定性 - 团队协作中,
composer.lock必须提交到 Git;删掉它再跑install,等价于跑了一次update -
composer install --dry-run可预览实际会装什么,比看 JSON 更可靠
composer update 重新解析依赖并更新 composer.lock
composer update 的核心动作是:用当前 composer.json 里的约束(比如 "monolog/monolog": "^2.0"),在 Packagist 上重新走一遍依赖求解,生成新的 composer.lock。它不关心旧锁文件里写了啥,只关心“现在理论上能装哪些版本”。
使用场景:
• 升级某个包到新主版本(如从 v1.x 到 v2.x)
• 修复安全漏洞(composer update --with-all-dependencies 或指定包名)
• 同步团队共享的依赖策略变更
- 默认会更新所有包,风险高;建议始终指定包名,例如
composer update phpunit/phpunit - 加
--with-dependencies会连带更新该包的子依赖,但不加的话,子依赖可能卡在旧版导致冲突 - 执行后务必提交新的
composer.lock,否则别人install时不会生效
为什么有时候 composer install 报 “Your requirements could not be resolved”?
这不是网络或权限问题,而是 composer.lock 里记录的某个包版本,在当前 PHP 版本、已安装扩展或平台配置下已经不兼容了——比如锁文件里记着 "guzzlehttp/guzzle": "6.5.5",但你本地 PHP 升到了 8.2,而这个旧版 Guzzle 不支持 PHP 8.2。
错误信息典型长这样:Your requirements could not be resolved to an installable set of packages.
后面跟着一堆 conflict 提示,根源往往藏在 platform config 或 lock 文件的 platform 项里。
- 先运行
composer show php和composer config platform.php,确认声明的 PHP 版本是否匹配实际环境 - 检查
composer.lock开头的platform字段,它可能锁死了旧 PHP 版本,导致 solver 拒绝所有新版包 - 临时解决可删
composer.lock再install(等于降级为update),但更稳妥的是用composer update --ignore-platform-reqs先过一遍,再手动修正 platform 配置
CI/CD 中该用 install 还是 update?
绝大多数构建流程应该只用 composer install,且必须带上 --no-interaction --optimize-autoloader --no-dev(除非测试需要 dev 包)。它的快、稳、可重现,是部署阶段的核心诉求。
而 composer update 应该只出现在开发机或依赖管理专用流水线里,比如 nightly security scan 或 major version bump PR。
- GitHub Actions 或 GitLab CI 中,不要出现
composer update,除非你明确要生成新 lock 文件并自动提交 - 如果项目用了
config.platform模拟低版本 PHP 测试兼容性,install仍会按锁文件装,但update可能因 solver 看到真实 PHP 版本而选错路径 - 私有包仓库(如 Satis 或 Private Packagist)响应慢时,
install因跳过依赖解析,比update更不容易超时
composer.json 不等于改依赖,不碰 composer.lock 就不算真正升级。很多人卡在这一步,不是命令不会打,是没意识到自己其实在维护一份三方协议。










