卡在writing lock file实际是依赖解析或下载阻塞,日志未刷新所致;需用-vvv定位卡点、禁用插件和缓存、检查网络与php配置。

Composer 执行卡死在 Writing lock file 这一步,90% 不是锁文件本身的问题,而是前面的依赖解析或下载阶段已陷入阻塞,只是日志没刷出来。
为什么卡在 Writing lock file 却实际没在写?
这个日志行是 Composer 解析完所有依赖、生成 composer.lock 内容后,准备将其写入磁盘前的最后一道确认。但它的触发前提是:所有包元数据已拉取完毕、版本已锁定、所有 require 和 require-dev 的约束已满足。如果卡在这里,说明 Composer 正在等待某个异步操作完成(比如某包的 ZIP 下载未返回、GitHub API 限流未恢复、或某个插件钩子挂起),但日志缓冲没及时刷新,让你误以为“停在这行”。
- 用
composer install -vvv查看完整输出,重点关注Downloading或Resolving packages后是否长时间无新日志 - 检查
~/.composer/cache/目录下是否有大量未完成的临时文件(如.zip.part),这是下载中断的典型痕迹 - 某些自定义插件(尤其是修改
pre-install-cmd或post-autoload-dump的)可能在锁文件写入前阻塞主线程
composer update 卡住时,先禁用插件和缓存
第三方插件和本地缓存是常见干扰源,尤其当它们依赖外部服务(如私有仓库 token 验证、Satis 索引同步)时,会拖慢甚至冻结整个流程。
- 临时跳过所有插件:
composer update --no-plugins - 强制忽略缓存(避免读取损坏的缓存包):
composer update --no-cache - 若使用了
composer config --global repo.packagist composer https://packagist.org类代理配置,尝试临时切回官方源:composer config --global repo.packagist composer https://repo.packagist.org - 检查
composer.json中是否有repositories指向响应极慢或不可达的私有源——注释掉它们再试
网络层问题:DNS、代理、IPv6 导致的静默超时
Composer 默认使用 cURL,而 cURL 在 DNS 解析失败或 IPv6 路由异常时,常表现为“无错误卡住”,而非报错。
- 运行
curl -v https://repo.packagist.org/packages.json,观察是否卡在Connected to repo.packagist.org后无响应 - 若公司网络强制走代理,确保
HTTP_PROXY和HTTPS_PROXY环境变量正确设置(注意大小写和协议前缀) - 尝试禁用 IPv6:
composer config --global disable-tls true && composer config --global secure-http false(仅调试用,勿长期开启) - Windows 用户特别注意:Git Bash 中
export设置的代理可能不被 Composer 识别,改用set HTTP_PROXY=...(cmd)或$env:HTTP_PROXY="..."(PowerShell)
PHP 配置与扩展冲突
某些 PHP 扩展(如 opcache、apcu)或内存限制会在 Composer 加载大量类/JSON 时引发不可预测的 hang,尤其在低内存容器环境。
- 临时禁用 opcache:
php -d opcache.enable=0 $(which composer) install - 提高内存限制:
php -d memory_limit=-1 $(which composer) update - 检查是否启用了
uopz或blackfire等调试扩展——它们可能拦截 Composer 的 autoloader 初始化 - Ubuntu/Debian 系统上,若安装了
php-curl但未启用,composer会 fallback 到 stream wrappers,速度极慢且易卡死;运行php -m | grep curl确认
真正卡死的位置往往藏在 Writing lock file 日志之前,盯着这行看只会错过关键线索。最有效的排查顺序是:开 -vvv、关插件、绕缓存、测网络、调 PHP 配置——而不是反复删 composer.lock 或重装 Composer。











