composer install 不更新 composer.lock 是设计使然,它仅按 lock 文件精确还原依赖;修改 composer.json 后需运行 composer update 才能同步 lock 文件。

composer install 为什么没更新 lock 文件
它根本不会更新 composer.lock,这是设计使然——composer install 只按 lock 文件精确还原依赖,连 composer.json 里改了版本号都不理。你改了 composer.json 后直接跑 install,它只会报错或静默忽略变更,绝不会自动同步 lock。
常见错误现象:composer install 后发现新包没装、旧包没升级、甚至提示 Your lock file does not contain a compatible set of packages。
- 要让 lock 文件反映
composer.json的修改,必须运行composer update - 如果只想更新某几个包(比如只升
monolog/monolog),用composer update monolog/monolog,避免全量重算依赖树 -
composer update --lock是个陷阱:它不更新依赖,只重新生成 lock 文件(比如修复格式或补 checksum),但不会拉新版本
composer update 锁定某个包的版本不升级
想保留 foo/bar 在 2.1.0,不让它被 update 升到 2.2.0?不能靠删掉 composer.json 里的版本约束——Composer 会按依赖图自动推导,很可能还是升了。
正确做法是显式固定版本,并禁用其子依赖的自动升级:
- 在
composer.json中写死:"foo/bar": "2.1.0"(用双引号,不用^或~) - 加
"prefer-stable": true防止意外切到 dev 分支 - 运行
composer update foo/bar --with-dependencies,再立刻composer install确认 lock 生效 - 注意:如果其他包强依赖
foo/bar:^2.2,Composer 会报冲突,这时得手动协调版本或加--ignore-platform-reqs(慎用)
lock 文件被误删或不同步时怎么安全恢复
团队协作中最常踩的坑:有人删了 composer.lock,或者 git 没提交它,导致本地 install 装出和线上不一样的依赖树——轻则行为不一致,重则 PHP Fatal error。
恢复的关键不是“重生成”,而是“对齐”:
- 先确认当前项目是否已有远端 lock 文件:
git checkout origin/main -- composer.lock(替换分支名) - 如果没有,且你信任
composer.json的约束,运行composer update --lock(仅重写 lock,不装包),再composer install验证 - 若
composer install报Root package requires ... but that version is not installable,说明composer.json写了不可达版本(比如"php": "8.4"),得先调低或改用--ignore-platform-reqs - 永远别在 CI 或生产环境用
composer update——那会绕过 lock,结果不可控
CI 环境下 lock 文件和依赖版本不一致的典型表现
CI 日志里出现 Warning: The lock file is not up to date with the latest changes in composer.json,或者测试突然失败,但本地 install 没问题——基本就是 lock 文件没提交、或提交了但没进 CI 构建上下文。
检查顺序很实际:
- 确认 CI 步骤中是否执行了
composer install(而非update) - 确认
composer.lock在 git 中真实存在且已git add提交(git ls-files | grep lock) - 确认 CI 工作目录干净:
git status --ignored看有没有被 .gitignore 掉的 lock 文件残留 - 某些 CI(如 GitHub Actions)缓存了 vendor 目录,但没缓存 lock 文件,会导致 vendor 和 lock 版本错位——缓存 key 必须同时包含
composer.lock的 hash
lock 文件不是辅助文件,它是依赖事实的唯一权威。只要它和 composer.json 不一致,或者它本身在不同环境里内容不同,就一定会在某个环节暴露出来。










