composer.lock 文件必须提交到 git,否则依赖版本不一致将导致测试通过但上线报错;install 依赖 lock 确保确定性,update 才重新解析依赖树,日常应仅用 install,update 需人工审查。

团队协作中,composer.lock 文件必须提交到 Git,否则根本谈不上“版本控制”——它不是可选配置,而是协作底线。
为什么 composer.lock 不能被忽略
不提交 composer.lock,等于把依赖解析权交给每个开发者的本地环境。哪怕 composer.json 里写的是 "guzzlehttp/guzzle": "^7.0",A 机器上装的是 7.9.2,B 机器上可能装出 7.10.0,而这个小版本升级恰好改了某个 HTTP header 的默认行为,结果测试通过、上线报错。
关键点在于:composer install 只读 composer.lock;composer update 才重新计算依赖树。没有 lock 文件,install 就退化成 update,失去确定性。
- CI/CD 流水线拉代码后执行
composer install,若无composer.lock,每次构建都可能拿到不同版本的包 - 生产环境部署脚本若依赖
composer install保证一致性,缺失 lock 文件会让发布变成掷骰子 - Git blame 查不到某次故障是否由某个依赖升级引入,因为升级记录根本没进版本历史
composer install 和 composer update 到底该用哪个
绝大多数日常操作只该用 composer install:它不碰 composer.json 的版本约束,只按 composer.lock 精确还原依赖树。
composer update 是一个有副作用的操作,它会忽略 composer.lock,重新走一遍依赖解析,生成新 lock 文件,并可能升级多个包——这本质上是一次“变更提案”,需要人工审查。
- 新增或修改
composer.json后,先运行composer update --dry-run看影响范围 - 确认要升级时,用
composer update vendor/package-name精确指定,避免连带升级无关包 - CI/CD 部署阶段严禁使用
composer update;上线前必须确保composer.lock已提交且与composer.json匹配
团队成员执行 composer install 报错的常见原因
错误信息如 Your lock file does not contain a compatible set of packages 或 Package xyz has a PHP requirement incompatible with your PHP version,通常不是命令问题,而是环境或流程断点。
- 本地 PHP 版本低于
composer.json中"php": "^8.1"的声明,需统一基础运行环境(Docker 或版本管理工具如phpbrew) -
composer.lock被手动编辑或未更新就提交,导致与composer.json不一致;应删掉 lock 文件后重新composer install(仅限本地调试) - 有人误用
composer update后只提交了composer.json,漏掉composer.lock;必须补交 lock 文件,否则其他成员install必然失败
前端资源协同时,composer.lock 的边界在哪
Composer 不管 node_modules,也不管 package-lock.json。但它可以通过 scripts 钩子触发前端构建,前提是这些钩子本身不改变 PHP 依赖状态。
例如在 composer.json 中定义:
"scripts": {
"post-install-cmd": ["@php -r \"file_exists('package.json') && system('npm ci && npm run build');\""],
"post-update-cmd": ["@php -r \"file_exists('package.json') && system('npm ci && npm run build');\""]
}
这种写法没问题,但要注意:
-
npm ci依赖package-lock.json,它和composer.lock是平行关系,各自独立提交 - 不要在
post-install-cmd里调用npm install,那会绕过 lock 文件,破坏前端构建一致性 - 如果项目用 Yarn,对应要用
yarn install --frozen-lockfile,语义等同于npm ci
真正容易被忽略的,是 lock 文件的“时效性”:它只锁定当前已解析出的依赖快照,一旦 composer.json 改动却忘记 update 并提交新 lock,协作链条就从第一环开始松动。











