composer install 总读 lock 文件是因为其设计目标是复现 composer.lock 记录的精确依赖版本,而非解析 composer.json;它忽略 composer.json 的变更,仅校验 lock 兼容性后按表安装。

composer install 为什么总读 lock 文件
因为 composer install 的设计目标就是复现 composer.lock 记录的精确依赖版本,不是重新解析 composer.json。它压根不看你的 composer.json 里有没有改过 require,只要 lock 存在且合法,就照着装。
常见错误现象:composer.json 新增了一个包,运行 composer install 却没装上;或者删了某个包,它还在 vendor 里 —— 这不是 bug,是预期行为。
- 想让新改动生效?必须用
composer update - 想跳过 lock 强制重算?不行,
composer install --ignore-platform-reqs也不绕过 lock - 临时不想用 lock?只能先删掉它(但别误删
composer.json)
composer update 和 install 的本质区别
composer update 才真正读 composer.json,调用依赖求解器重新计算所有版本约束,生成新的 lock;而 composer install 只校验 lock 是否与当前平台兼容,然后按表发货。
使用场景差异明显:
- CI/CD 部署、团队协作安装:用
composer install—— 快、确定、可重现 - 开发中加依赖、升版本、解决冲突:用
composer update - 只更新某几个包?写清楚包名:
composer update monolog/monolog guzzlehttp/guzzle
性能影响:update 可能卡几十秒,尤其网络差或依赖树深;install 通常秒级。lock 文件就是为这个优化存在的。
怎么安全地“重新计算依赖”而不炸掉线上环境
直接 composer update 很危险 —— 它默认更新所有包到符合约束的最新版,可能引入不兼容变更。要控制范围,得靠参数和锁策略。
- 只更新
composer.json中明确写出的包(忽略 require-dev):composer update --no-dev - 锁定 PHP 版本等平台要求,避免误装高版本依赖:
composer update --with-all-dependencies要慎用 - 想保留大部分旧版本,只升级某一个?先确认它的约束是否宽松(比如
"^2.0"),再跑composer update vendor/package-name - 更新后务必检查
git diff composer.lock,重点关注 major 版本号跳变
删 lock 文件不是万能解,反而容易埋坑
有人以为删了 composer.lock 再 install 就等于重算,其实只是触发一次新的 update 流程 —— 但这次没有历史 lock 约束,结果更不可控。
典型翻车点:
- 不同人删 lock 后 run install,得到的依赖树可能完全不同(尤其是用了
~或^这种模糊约束时) - CI 环境里删 lock + install,等于把构建一致性全交给网络和 packagist 当前状态
- 某些私有包如果没设
dist源,删 lock 后可能因 checksum 失败直接中断
真要从头来?先 rm composer.lock,再 composer install --no-cache,但前提是所有人同步 commit 新 lock,且已人工验证过依赖兼容性。










