composer.lock 是 composer 解析 composer.json 后生成的精确依赖快照,包含包名、版本、源地址、sha256 校验值及完整依赖树,非缓存而是强制契约;install 时直接还原 lock 内容,忽略 composer.json 的版本约束。

composer.lock 是怎么生成的?不是缓存,是快照
它不是临时文件,也不是可删可不删的辅助产物——composer.lock 是 Composer 解析完 composer.json 后,把整个依赖树“拍下来”的精确快照。这个过程包含三类关键信息:name、version、dist 或 source(下载地址)、sha256(校验值),以及每个包自己的 require 子树。一旦生成,后续 composer install 就只读它,完全跳过版本约束解析。
为什么 composer install 不看 ^ 和 ~?
composer install 的设计目标就是“还原”,不是“决策”。它根本不解析 composer.json 里的任何版本约束符号(比如 ^2.0 或 ~1.2.3),而是直接按 composer.lock 里写死的 version 去拉包、校验 sha256、解压到 vendor/。这意味着:
- 即使你把
composer.json里的"monolog/monolog": "^2.0"改成"^3.0",只要不运行composer update,install依然装 2.x - 如果
lock文件缺失或损坏,install会退化为update行为,重新解析约束——这正是很多 CI 构建失败的根源 -
install --no-dev也只过滤lock里已记录的 dev 包,不会动态重算依赖图
composer update 真正在做什么?不只是升级
它触发的是完整依赖图重计算,底层用 SAT 求解器处理所有 require 关系和版本约束冲突。具体步骤包括:
- 加载
composer.json中全部require和require-dev条目 - 递归解析每个包的
composer.json(从 Packagist 或自定义仓库),构建完整依赖图 - 对每个包尝试满足所有上游约束,若无解则报
Your requirements could not be resolved - 成功后,把最终选定的每个包的精确版本、源地址、哈希值、子依赖关系,序列化写入
composer.lock
注意:哪怕只是改了 config.platform.php,也会导致依赖图重算——因为平台信息参与版本兼容性判断。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
哪些改动必须提交新 composer.lock?
只有影响依赖解析结果的变更才需要运行 composer update 并提交新 lock。典型场景包括:
- 修改
require或require-dev中的包名或版本约束(如把"guzzlehttp/guzzle": "^7.0"改为"^8.0") - 增删包(
composer require foo/bar或手动编辑composer.json) - 调整
config.platform、minimum-stability或启用prefer-stable
而改 autoload、scripts、description 这类字段,完全不影响依赖树,不需要碰 lock 文件。
真正容易被忽略的是:团队协作中遇到 composer.lock 冲突时,绝不能手动合并 JSON。它不是普通配置文件,而是完整依赖图的序列化结果。冲突时应先 checkout 任一分支的 lock,删掉 vendor/,再跑 composer install——如果不匹配,Composer 会明确报错,而不是静默出错。










