composer install 秒装是因为只读取 composer.lock 文件并直接解压安装,不进行依赖解析;而 composer update 会重新计算整个依赖图,耗时较长。

composer install 为什么总是秒装?因为它根本不“算”
它只读 composer.lock,按里面写死的版本号、哈希值、下载地址,直接拉包解压进 vendor/。不查 Packagist、不跑依赖求解器、不比新版本、不改 lock —— 纯 IO 操作。
常见错误现象:Your lock file does not contain a compatible set of packages,说明 composer.json 和 composer.lock 对不上,比如别人改了 json 却没提交 lock,或你本地删过 lock 文件。
- 新人克隆项目后,必须先
git pull拉最新 lock,再运行composer install - CI/CD 流水线和线上部署脚本里,只允许出现
composer install --no-dev,绝不能有update - 如果 lock 缺失,install 会退化为临时解析 json 并生成新 lock —— 这只是初始化行为,不是常态
composer update 为什么卡住十几秒?它在重画整张依赖图
update 主动忽略 composer.lock,把 composer.json 当处方重新审方:向镜像源发大量元数据请求,调用 SAT 求解器反复验证 PHP 版本、扩展、嵌套依赖之间的兼容性,最后选出一组“当前满足所有约束的最新组合”。
性能影响明显:一个中等规模项目(50+ 直接依赖),update 可能触发 200+ HTTP 请求,CPU 占用飙升,而 install 通常在 1 秒内完成。
- 想升级单个包?用
composer update monolog/monolog,避免全量重算 - 刚加了新包?别手敲 install 或 update,用
composer require guzzlehttp/guzzle,它自动写 json、装包、更新 lock - 安全漏洞修复?先
composer update --dry-run看会升哪些版本,确认无风险再执行
锁文件不是缓存,是契约——团队不提交 lock 就等于没协作
composer.lock 是可重现安装的唯一依据。它记录的不是“某个包的大致范围”,而是每个包的精确版本、完整哈希、源类型(dist/vcs)、安装路径 —— 这才是“三年后重装,结果完全一样”的技术基础。
容易踩的坑:
- Git 忽略
composer.lock→ 所有人 install 出来的 vendor 都可能不同,CI 构建结果不可控 - 生产环境误跑
composer update→ lock 被覆盖,下次 install 就装不到原来那套,线上行为突变 - 手动编辑
composer.json后没运行 require/update → lock 未同步,下次 install 会报错或漏装
什么时候该用哪个命令?看动作目标,不是看“是不是开发机”
核心判断只有一条:你要“复现已知状态”,还是“主动变更依赖”?
- 克隆项目、部署上线、CI 构建 →
composer install(稳) - 修复 CVE、接入新 API、替换废弃包 →
composer update(慎),且必须测试通过后提交新 lock - 新增功能需引入新包 →
composer require laravel/sanctum(准),它内部封装了受控的 update + lock 写入
真正复杂的地方在于:lock 文件一旦被破坏(比如多人同时修改 json 但只有一人提交 lock),整个依赖一致性就崩了,而这种问题往往在线上出错时才暴露——那时已经晚了。










