composer install 不解析新依赖,只按 lock 文件还原;它严格依据 composer.lock 中记录的包名、精确版本和哈希值安装,不重新计算依赖图;若 lock 缺失或损坏,则退化为 composer update 行为,触发 sat 求解器重算依赖树。

composer install 不解析新依赖,只按 lock 文件还原
它根本不会重新计算依赖图,而是严格照着 composer.lock 里记录的每个包名+精确版本+哈希值去 vendor/ 下装东西。如果你删了 composer.lock,composer install 就会退化成 composer update 的行为——开始调用 SAT 求解器解析整个依赖树。
常见错误现象:
- 本地
composer install正常,CI 失败报Class not found→ 很可能 CI 没拉到最新的composer.lock,或用了不同版本 Composer 解析出不同子依赖 - 执行
composer install却提示 “Resolving dependencies…” 卡住 → 说明composer.lock不存在或损坏,它正在强行解析,此时已不是纯安装,而是进入 update 模式
关键点:
-
composer install的前提是你有合法、未被手动编辑过的composer.lock - 团队必须提交
composer.lock,且禁止用文本编辑器改它(哪怕只改一个逗号) - 想锁定某个间接依赖(如
monolog/monolog),不能在根composer.json里加 require,而应通过replace或conflict干预解析逻辑
嵌套依赖版本从哪来:lock 文件 + 根 composer.json 共同决定
composer.lock 里存的是完整快照:每个包的 name、version、source、dist、require 列表,甚至包括它的 autoload 配置。但它的 version 字段不是“最终安装版”,而是“当时 resolve 出来的结果”。真正约束这个结果的,是两层信息:
- 根
composer.json中的require约束(如"guzzlehttp/guzzle": "^7.0") - 各包自身
composer.json中声明的require(如 guzzlehttp/guzzle 要求"php": "^7.2.5 || ^8.0"、"psr/http-client": "^1.0")
所以当你运行 composer update 时,Composer 才会递归读取所有已知包的 composer.json,构建整张依赖图,再用 SAT 求解器找满足全部约束的唯一解。而 composer install 只负责把这张图的某次快照“还原”出来。
注意:composer show --tree 显示的层级,是 lock 文件里已记录的结构;如果某个包没出现在 lock 里,它就不会出现在树中——哪怕它的 composer.json 里写了 require,也没用。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
为什么有时看到的依赖树和预期不一致?
因为 composer show --tree 默认包含 require-dev,而生产环境不该装这些。比如 phpunit/phpunit 可能在自己 composer.json 里写了 "autoload": {"psr-4": {"App\": "../src/"}},这会把你的 src/ 加进它的自动加载路径;而你又用了它的测试基类,运行时就形成隐式闭环。
排查建议:
- 用
composer show --tree --no-dev查生产依赖链 - 用
composer why --tree --dev <package></package>查开发依赖引入路径 - 临时注释掉
require-dev下非核心工具(如phpunit/phpunit、phpstan/phpstan),再试composer update --dry-run -v - 搜所有
vendor/*/composer.json里的../、../../、src/—— 这些路径极易引发跨包 autoload 冲突
循环依赖卡死时,install 命令其实无能为力
一旦 composer install 开始卡在 “Resolving dependencies…” 超过 30 秒、CPU 拉满,说明它被迫进入解析模式,而 SAT 求解器已在闭环里打转。这时候等没用,composer install 不提供诊断能力。
唯一实锤手段是:
- 立刻运行
composer update --dry-run -v - 重点看输出末尾是否重复出现同一路径,例如:
vendor/a → vendor/b → vendor/c → vendor/a—— 出现两次即确认闭环 -
composer depends --tree必须满足两个前提才有效:项目已成功执行过composer install(保证 lock 有完整快照),且必须带--tree参数
破环只有三种真实可行方式:切断 autoload 路径、移除 require-dev 污染、或用 replace / conflict 强制单向依赖。没有跳过选项,也没有“忽略警告继续装”的安全路径。










