resolving dependencies卡住本质是本地sat求解器暴力穷举版本组合,非网络问题;提速关键在收紧约束、提交lock文件、移除冗余dev依赖、禁用xdebug、增加内存限制。

Resolving dependencies卡住几十秒,本质是SAT求解器在本地暴力穷举
这不是网络慢,也不是镜像没配对——Resolving dependencies... 阶段完全不发HTTP请求,Composer在本地跑一个布尔可满足性(SAT)求解器,逐个尝试所有包版本组合,直到找到满足全部require、conflict、PHP版本等约束的解。项目有200+依赖、composer.lock超8MB时,单核CPU会持续满载。
常见诱因包括:
-
composer.json里写了过于宽泛的约束,比如"php": "*"或"monolog/monolog": "^1.0 || ^2.0 || ^3.0" - 大量
dev-main或dev-develop分支未锁定,每次都要重新解析最新提交 - 启用了
xdebug:会让SAT求解慢5–10倍,php -v输出含xdebug就基本能确认 -
memory_limit低于512M:默认128M在大型项目中直接触发OOM,表现为Segmentation fault或中途退出
真正有效的提速操作不是换镜像,而是动lock文件和约束粒度
中文镜像(如阿里云)只加速Loading composer repositories和Downloading,对Resolving dependencies零作用。想让解析变快,得从输入源头下手:
- 永远提交
composer.lock到Git——它缓存了上一次成功求解的结果,composer install直接跳过整个SAT过程 - 运行
composer update --lock(不带包名):压缩composer.lock体积,合并重复字段,实测可减小30%+ JSON大小 - 删掉长期不用的
require-dev,比如旧版phpstan/phpstan、已迁出的测试辅助工具——它们不安装,但参与求解 - 用
composer why-not some/package查清某个包为何被拉入依赖树,再决定是否收紧其版本约束或剔除上游依赖
--no-dev不能跳过dev依赖的解析,只是不安装
这是最常被误解的一点。--no-dev参数只影响安装阶段,所有require-dev里的包仍会被完整纳入SAT求解范围。如果你的composer.json里还留着"phpunit/phpunit": "^9.0",即使加了--no-dev,它照样拖慢解析速度。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
正确做法是:
- 把仅本地使用的工具(如
phpunit、phpcs)移到全局安装:composer global require phpunit/phpunit - 或者彻底从
composer.json中移除,改用composer exec phpunit调用(前提是它仍在vendor/bin/里) - 私有包务必在
composer.json中声明"archive": {"exclude": ["/tests", "/docs"]},否则composer.lock会为被排除路径生成冗余哈希项
别碰prestissimo,也别信“二进制加速”这种说法
hirak/prestissimo早在2021年就停止维护,且与Composer 2.x原生的cURL multi并行机制冲突。强行启用会导致:
- 内存溢出(OOM),尤其在CI环境中
- Segmentation fault错误,进程直接崩溃
- 部分包下载失败后反复重试,反而延长总耗时
Composer 2.9.6已深度优化SAT算法与JSON解析路径,真实瓶颈从来不在下载层。真正该调的是:
-
COMPOSER_MEMORY_LIMIT=-1(临时验证是否内存不足) -
php -d memory_limit=1G $(which composer) install(生产环境稳妥写法) - 删掉
vendor/和composer.lock后,用composer install --no-cache重装——旧lock可能引用已下线包,触发回退查找逻辑
复杂点在于:SAT求解没有“开关”可关,它由约束表达式本身决定搜索空间大小。你写的每一个||、每一个*、每一个未锁定的分支,都在指数级扩大它的工作量。










