composer install 严格按 composer.lock 中记录的精确版本安装,不读取 composer.json 的约束,确保环境一致;composer update 则根据 composer.json 重新解析并更新依赖及 lock 文件。

composer install 只装 composer.lock 里写死的版本
它不读 composer.json 的版本约束,只按 composer.lock 中记录的精确版本(包括哈希值)下载安装。这是 CI/CD、生产环境部署的标准做法,确保所有人装的包完全一致。
常见错误现象:composer install 报错 Package X is not installed,往往是 composer.lock 缺失或损坏;或者你改了 composer.json 却没运行 composer update,结果 install 仍按旧 lock 装,新依赖根本不会出现。
- 必须存在
composer.lock,否则直接报错退出(除非加--ignore-platform-reqs等非常规参数) - 不修改
composer.lock,也不检查composer.json是否和 lock 匹配(但会警告不一致) - 速度快,因为跳过依赖解析,直接拉取已知版本
composer update 重新解析依赖并更新 composer.lock
它读 composer.json 的版本范围(如 "monolog/monolog": "^2.0"),联网查满足条件的最新兼容版本,再递归解决所有子依赖冲突,最后把结果写进 composer.lock。
使用场景:开发阶段引入新包、升级大版本、修复安全漏洞、或需要尝鲜某功能时。但别在生产服务器上乱跑 —— 它可能把 phpunit 升到不兼容当前 PHP 版本的 v10,而你毫无察觉。
- 默认同时更新所有包;想只更某个,加包名:
composer update monolog/monolog - 加
--with-all-dependencies会连带更新间接依赖(比如 A 依赖 B,B 依赖 C,C 也会被重算) - 如果
composer.json和composer.lock已不一致,update会强制覆盖 lock,install则只警告
为什么 composer install 有时会“偷偷”变行为?
关键看有没有 composer.lock,以及你的 PHP 环境是否匹配 lock 文件里记录的 platform 配置(比如 "platform": {"php": "8.1.0"})。
容易踩的坑:
-
composer install在 PHP 8.2 环境下,遇到 lock 里锁的是 PHP 8.1 专属的包版本,可能跳过某些包(或报Your requirements could not be resolved) - 团队有人删了
composer.lock提交,其他人install就退化成update行为,导致环境漂移 -
composer install --no-dev会忽略require-dev,但 lock 文件若没区分 dev/main,可能导致本地测试用的包缺失
该提交 composer.lock 吗?
绝大多数项目必须提交。它不是“中间产物”,而是依赖快照,相当于 package-lock.json 或 Pipfile.lock。
例外极少:库项目(library)、SDK、或明确要求使用者自行 resolve 依赖的组件 —— 这类项目通常只维护 composer.json,且文档会写明“不要提交 lock”。但你写的 Web 应用、Laravel 项目、WordPress 插件?锁文件必须在 Git 里。
性能与兼容性影响:
- 不提交 lock → 每次 install 实际是 update,CI 构建时间变长,不同机器装出不同版本
- lock 文件包含哈希校验,能防包源投毒;没它,就靠 HTTPS 和签名,防护弱一层
- PHP 大版本升级时,先
update再提交 lock,比手动改 json 更安全(Composer 会自动排除不兼容包)
最常被忽略的其实是 lock 文件里的 content-hash 字段 —— 它校验的是 composer.json 内容本身。哪怕你只多打了个空格,hash 就变,Composer 就会警告 lock 和 json 不匹配。这个细节决定你能不能安静地 deploy。











