curl error 28 根本原因是 DNS 解析或 TLS 握手超时,非下载慢;首选方案是切换国内镜像源(如阿里云),其次排查本地 DNS 和 OpenSSL 证书问题。

curl error 28 是 Composer 在下载包时最常遇到的网络超时错误,本质不是 Composer 本身的问题,而是底层 cURL 在连接或接收响应时耗时超过预设阈值后主动中止。直接调高超时参数往往治标不治本——真正卡住的通常是 DNS 解析、TLS 握手或镜像源响应慢,而非单纯“下载太慢”。
为什么改 CURLOPT_TIMEOUT 不一定有用
Composer 内部使用 cURL 下载,但它不暴露原始 cURL 参数配置接口,你无法像写 PHP 脚本那样直接设 CURLOPT_TIMEOUT 或 CURLOPT_CONNECTTIMEOUT。强行修改 PHP 的 max_execution_time 或 default_socket_timeout 也无效,因为 Composer 启动的是独立进程,且其网络层封装了重试与并发逻辑。
常见误操作包括:
- 修改
php.ini中的max_execution_time = 300→ 对 Composer CLI 无影响 - 在命令前加
timeout=300 composer install→ shell 环境变量不被 Composer 识别 - 以为
composer config -g github-oauth.github.com token能加速 → 这只影响 GitHub API 限速,和 packagist 主体下载无关
优先换国内镜像源(最有效、一步到位)
repo.packagist.org 官方源在大陆访问极不稳定,DNS 解析常超 15 秒,TLS 握手失败率高,这是 curl error 28 的主因。换成阿里云、腾讯云等镜像后,90%+ 场景可秒解。
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
其他可用镜像(任选其一):
https://www.php.cn/link/aad92567225d700b4408b63e7fe0f9c8https://www.php.cn/link/f7d90eaf20a3c676e36710d069f8d8b8-
https://www.php.cn/link/dc02ae8025eef0ecde61b00bb780abdb(已逐步停用,不推荐新项目)
⚠️ 注意:如果项目里已有 composer.json 且含自定义 repositories,全局镜像可能被覆盖。此时应删掉项目级配置,或统一用:
composer config repo.packagist composer https://mirrors.aliyun.com/composer/(不加
-g,仅对当前目录生效)
仍失败?检查 DNS 和 OpenSSL 证书链
即使换了镜像,仍有小概率报错,典型现象是:
- 错误信息含
Resolving timed out after XXXX milliseconds -
composer diagnose显示HTTPS connection to https://www.php.cn/link/5b4ba6e852444462a8e1223fc42e1af8 failed -
ping mirrors.aliyun.com正常,但curl -I https://www.php.cn/link/6060b7fe96c78f32d3a8c14897f1af61卡住
这说明问题出在本地 TLS 层或 DNS:
- Windows 用户常见于系统自带 DNS(如 114.114.114.114)解析
mirrors.aliyun.com缓慢 → 改用8.8.8.8或223.5.5.5 -
macOS/Linux 可临时测试:
echo "nameserver 223.5.5.5" | sudo tee /etc/resolv.conf
- OpenSSL 证书过期(尤其 XAMPP/MAMP 用户)→ 更新系统根证书,或让 Composer 跳过验证(仅调试用):
composer config -g secure-http false
(生产环境禁用)
极少数场景才需调整 Composer 超时行为
Composer 自身提供两个可调参数,但仅对「包元数据拉取」阶段有效(即 packages.json、p2/*.json),不控制 ZIP 包下载:
-
composer config -g http.ssl.certificate:指定 PEM 证书路径(极少需设) - 更实用的是延长重试与并发等待:
composer config -g bitbucket-oauth.bitbucket.org '{"consumer-key":"xxx","consumer-secret":"yyy"}'(仅限 Bitbucket 私有库)
真正影响 ZIP 下载的是 PHP 的 default_socket_timeout(单位秒),可在运行时覆盖:
php -d default_socket_timeout=600 /usr/local/bin/composer install
但注意:该设置对所有 socket 操作生效,若机器本身网络异常,单纯延长时间只会让失败来得更晚。
换镜像源是解决 curl error 28 的第一动作,不是“试试看”的备选方案——它是事实标准。DNS 和证书问题容易被忽略,但它们藏在错误日志背后,不排查就反复重试只是浪费时间。










