composer.lock 是项目依赖的精确快照,记录各包确切版本、哈希值、源类型及完整依赖树,确保 install 结果一致;必须提交至 Git,禁用 update 于生产/CI,冲突时应先合并 composer.json 再执行 update 生成新 lock。

composer.lock 是依赖的“快照”,不是临时文件
它不是生成完就扔的中间产物,而是项目依赖状态的精确记录:每个包的确切版本(比如 monolog/monolog: 3.5.0)、完整哈希值、源类型(dist 或 source)、甚至嵌套依赖的完整树结构。没有它,composer install 每次都要重新解析 composer.json 中的 ^2.0 或 ~3.4 这类模糊约束——不同时间、不同机器、不同 Composer 版本,结果可能差一个补丁号,而这个差值就足以触发 Class not found 或方法签名不匹配。
团队里不提交 lock 文件 = 把线上故障概率交给运气
常见错误现象:CI 构建失败但本地能跑、预发环境正常,上线后 500、Git 切回上周 commit,composer install 装出来的却是新版本依赖。这些几乎全是没提交 composer.lock 导致的。它让团队共享一个“已验证过”的依赖组合:
- 新成员克隆项目后,
composer install一步到位,不用猜“当时到底装了啥” - CI/CD 流水线靠它跳过解析,直接下载锁定包,构建快且稳定
- 生产部署时,
composer install --no-dev能 100% 还原测试通过的那套依赖 - 安全扫描工具(如
composer audit)必须依赖composer.lock才能识别深层漏洞
日常该用 install 还是 update?一句话分清
install 是还原,update 是变更——绝大多数时候你只需要 composer install:
- 刚克隆项目、跑 CI、上线部署 → 无条件用
composer install - 新增依赖 → 先
composer require guzzlehttp/guzzle(自动更新 lock),再提交composer.lock - 升级已有依赖 → 显式运行
composer update symfony/console,验证通过后提交新composer.lock - 绝对禁止在 CI 或生产环境执行
composer update,也不要在未改composer.json的情况下手动 touchcomposer.lock
Git 冲突时千万别手改 lock 文件
composer.lock 是自动生成的 JSON,字段多、嵌套深、顺序敏感。手动合并极易破坏结构,轻则 autoload 失败,重则整个依赖树错乱。标准解法只有一条路径:
- 先解决
composer.json的冲突(比如两人同时加了包,或改了同一包的版本) - 保存合并后的
composer.json - 运行
composer update(或更精准的composer update vendor/package) - 提交新生成的
composer.lock
最容易被忽略的一点:不同操作系统(Linux/macOS/Windows)下生成的 composer.lock 可能因路径分隔符或换行符差异产生看似无关的 diff;建议在 composer.json 中配置 "platform": {"php": "8.2.0"} 统一模拟环境,并启用 Git 的 core.autocrlf 规范化处理。










