cohttpclient 类在 swoole v5.0+ 中已被彻底移除,v4.8.0 起废弃;应改用 swoolecoroutinehttpclient,并确保启用 http_client 模块及协程环境。

CoHttpClient 类不存在?先确认 Swoole 版本和扩展加载状态
不是代码写错了,而是 CoHttpClient 在 Swoole v5.0+ 已被彻底移除——它早在 v4.8.0 就开始标记为废弃,v5.0 正式删除。你现在看到的“类不存在”,大概率是因为升级到了新版 Swoole 却还在沿用旧文档写法。
验证方式很简单:php --ri swoole 查看输出中的 version 行;再检查有没有 coroutine => enabled 和 http_client => enabled(后者在 v4.8+ 后拆为独立模块,非默认开启)。
- v4.8.x:类名是
SwooleCoroutineHttpClient,不是CoHttpClient(Co是旧版 alias,v4.6+ 起已弃用) - v5.0+:必须用
SwooleCoroutineHttpClient,且需确保编译时启用了--enable-http-client - 如果
php --ri swoole里没看到http_client项,说明扩展模块没启用,仅靠enableCoroutine()不够
SwooleCoroutineHttpClient 初始化失败的常见原因
即使类存在,new SwooleCoroutineHttpClient() 仍可能返回 false 或静默失败,核心在于协程上下文缺失或 DNS 配置不当。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
- 必须在
Co un()内部、或go()启动的协程中创建实例;在onRequest回调里直接 new 是 OK 的,但在onWorkerStart里 new 就会失败(无协程环境) - 默认不启用协程 DNS 解析,
localhost或域名会卡在gethostbyname()上;必须显式设置['enable_coroutine_dns' => true],或改用 IP 地址绕过 - 若目标地址是
https://,但未设置ssl_host_name,SNI 握手阶段可能静默挂起——尤其调用云服务(如阿里云 OSS)时高频出现
替代方案:不用 Client 类也能发 HTTP 请求?
真不想碰 SwooleCoroutineHttpClient 的繁琐配置,有两个更轻量的选择:
-
file_get_contents('http://...')可用,但只限于http://和https://协议;一旦 URL 变成file:///或php://,立刻退化为同步阻塞,且无任何警告 - 用第三方协程 HTTP 库,比如
YurunHttp或hyperf/http-client,它们底层自动适配SwooleCoroutineHttpClient,对外提供类似 Guzzle 的接口,对 SDK 兼容性更好(例如阿里云 OSS SDK v2.4+ 已原生支持协程)
最后检查:SSL/TLS 握手失败时没有报错怎么办
现象是 $client->get() 一直不返回,swoole_get_last_error() 为空,CPU 占用低——这基本锁定在 TLS 握手卡死。
- 先用命令行验证服务端是否正常响应:
openssl s_client -connect api.example.com:443 -servername api.example.com,看是否有Verify return code: 0 (ok) - 客户端侧必须设置
['ssl_host_name' => 'api.example.com'],否则 SNI 扩展不发送,某些 CDN 或网关会直接拒绝 - 私有 CA 证书场景下,不要设
ssl_verify_peer => true,改用ssl_cafile指向你的根证书路径(绝对路径!daemon 模式下相对路径会失效)
最常被忽略的一点:v5.0+ 的 SwooleCoroutineHttpClient 默认启用 TLS 1.3,但老设备(如部分 Android WebView)不支持,得手动降级:set(['tls_version' => 'TLSv1.2'])。










