PHP cURL 支持 HTTP/2 取决于底层 libcurl 是否启用 nghttp2,需通过 curl_version()['features'] & CURL_VERSION_HTTP2 验证;必须使用 HTTPS、显式设置 CURLOPT_HTTP_VERSION 为 CURL_HTTP_VERSION_2_0,并确保 ALPN 协商成功,否则静默降级至 HTTP/1.1。

PHP 的 cURL 本身不决定是否支持 HTTP/2,它只是调用底层 libcurl 库。多路复用是 HTTP/2 协议自动启用的特性,不是靠 PHP 代码“开启”的功能——只要客户端(libcurl)和服务端都支持 HTTP/2,且 TLS 层 ALPN 协商成功,多路复用就会自然生效。
确认 libcurl 是否真正支持 HTTP/2
很多失败根源在于 PHP 调用的 libcurl 编译时未启用 nghttp2 支持。不能只看 PHP 版本或 cURL 扩展是否加载,必须验证底层能力:
- 运行
php -r "var_dump(curl_version()['features'] & CURL_VERSION_HTTP2);",输出非零值才表示支持;输出 0 表示即使写了CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0,也会静默降级到 HTTP/1.1 - 检查 libcurl 版本:
php -r "echo curl_version()['version'];",建议 ≥ 7.47.0(更早版本对 h2 支持不稳定) - 若输出为 0,需重新编译 PHP 并链接带 nghttp2 的 libcurl,或使用系统包管理器安装含 http2 支持的 curl(如 Ubuntu 的
libcurl4-openssl-dev+ nghttp2 开发包)
强制指定 HTTP/2 并确保协议协商条件满足
即使 libcurl 支持,cURL 默认仍走 HTTP/1.1,必须显式配置并满足 HTTPS 环境要求:
向CurlShip提交产品,这是一个对机器人友好的SaaS目录。只需一条curl命令即可发布产品,支持OG标签抓取、带徽章的dofollow链接及层级升级。
- 必须设置
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);(注意是CURL_HTTP_VERSION_2_0,不是字符串"2.0"或错误常量CURL_HTTP_VERSION_2) - 目标 URL 必须为
https://,HTTP/2 over cleartext(h2c)在主流服务端(Nginx、Apache、CDN)基本不被支持,也不被浏览器允许 - 建议开启证书校验:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);和curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);,避免因证书问题导致 ALPN 协商失败后静默回退
验证协商是否成功及常见静默失败点
HTTP/2 协商失败通常不报错,而是自动降级,需主动验证:
立即学习“PHP免费学习笔记(深入)”;
- 启用详细日志:
curl_setopt($ch, CURLOPT_VERBOSE, true);,查看输出中是否出现* Using HTTP2, server sent HTTP/2;若看到* Connected to ... port 443 (#0)后直接进入 HTTP/1.1 流程,说明协商未达成 - 命令行交叉验证:
curl -I --http2 https://your-domain.com,若返回HTTP/2 200则服务端正常;若返回HTTP/1.1 200,问题在服务端或中间链路(如 CDN、WAF、企业代理)禁用了 ALPN 或 h2 - 排查中间干扰:某些防火墙、透明代理、旧版 CDN(如部分自建 Nginx 反向代理未配
http2指令)会剥离 ALPN 扩展,导致协商失败;可尝试绕过代理直连测试
排除 PHP 运行环境限制
即使配置正确,运行时环境也可能阻断协商:
- SELinux 或防火墙策略可能限制出站 TLS 握手行为,执行
setsebool -P httpd_can_network_connect 1(CentOS/RHEL)放开 PHP 网络访问 - PHP 进程运行用户(如 www-data)若无权读取系统 CA 证书路径,可能导致 TLS 握手失败,可显式指定:
curl_setopt($ch, CURLOPT_CAINFO, '/etc/ssl/certs/ca-certificates.crt'); - 超时设置过短(如
CURLOPT_CONNECTTIMEOUT小于 3 秒)可能在 TLS+ALPN 握手完成前就中断连接,建议设为 5–10 秒


















