本文目录导读:

在 PHP 中实现协程 HTTP 客户端,主要依赖于 Swoole 或 Workerman 等扩展。Swoole 是目前最主流的选择,因为它原生内置了协程 HTTP 客户端。
以下是关于 PHP 协程 HTTP 客户端的全面指南:
为什么使用协程 HTTP 客户端?
传统的 PHP HTTP 请求(如 curl)是同步阻塞的,无法并发,协程客户端可以:
- 并发执行:同时发送多个请求,总耗时取决于最慢的那个。
- 高吞吐量:在长连接场景下性能极高。
- 非阻塞:协程切换开销远小于进程/线程切换。
Swoole 协程 HTTP 客户端
基础用法(HTTP/1.1)
<?php
use Swoole\Coroutine\Http\Client;
use function Swoole\Coroutine\run;
run(function () {
$client = new Client('www.example.com', 80);
$client->set(['timeout' => 5]);
// 发起 GET 请求
$client->get('/');
echo "Status: " . $client->statusCode . PHP_EOL;
echo "Body: " . $client->body . PHP_EOL;
$client->close();
});
并发请求(核心优势)
这是协程的最大价值——并发请求:
<?php
use Swoole\Coroutine\Http\Client;
use function Swoole\Coroutine\run;
use function Swoole\Coroutine\go;
run(function () {
$urls = [
'https://api.github.com',
'https://httpbin.org/get',
'https://example.com',
];
$start = microtime(true);
$results = [];
// 为每个 URL 创建一个协程
foreach ($urls as $index => $url) {
go(function () use ($url, &$results, $index) {
$client = new Client(parse_url($url, PHP_URL_HOST), 443, true); // true = SSL
$client->set(['timeout' => 10]);
$path = parse_url($url, PHP_URL_PATH) ?: '/';
$client->get($path);
if ($client->statusCode === 200) {
$results[$index] = $client->body;
} else {
$results[$index] = "Error: " . $client->statusCode;
}
$client->close();
});
}
// 等待所有协程完成(run 函数自动等待)
echo "Total time: " . (microtime(true) - $start) . " seconds\n";
print_r($results);
});
并发批量请求(使用 Channel 控制并发数)
为了避免产生过多协程,可以使用 Channel 作为并发限制:
<?php
use Swoole\Coroutine\Channel;
use function Swoole\Coroutine\run;
use function Swoole\Coroutine\go;
run(function () {
$urls = [/* 100 个 URL */];
$concurrency = 10; // 同时最多 10 个请求
$channel = new Channel($concurrency);
$results = [];
// 生产者:填充任务
go(function () use ($channel, $urls) {
foreach ($urls as $url) {
$channel->push($url); // 会阻塞,直到有空间
}
$channel->close(); // 关闭通道,表示没有更多任务
});
// 消费者:N 个协程处理任务
for ($i = 0; $i < $concurrency; $i++) {
go(function () use ($channel, &$results) {
while (true) {
$url = $channel->pop();
if ($url === false) break; // 通道关闭,退出循环
$client = new Client(parse_url($url, PHP_URL_HOST), 443, true);
$client->get('/');
$results[$url] = $client->statusCode;
$client->close();
}
});
}
});
高级特性
HTTPS 与证书验证
$client = new Client('www.baidu.com', 443, true); // 启用 SSL
$client->set([
'ssl_host_name' => 'www.baidu.com', // SNI
'ssl_verify_peer' => false, // 开发环境可关闭证书验证
]);
连接复用(Keep-Alive)
协程客户端默认支持 keep-alive,在并发场景下自动复用连接,可以通过 set 方法配置:
$client->set([
'keep_alive' => true,
'keep_alive_idle_time' => 60, // 空闲 60 秒后关闭
]);
设置请求头与 Cookie
$client->setHeaders([
'User-Agent' => 'MyCoroutineClient/1.0',
'Accept' => 'application/json',
'Cookie' => 'session_id=abc123; user_id=42',
]);
上传文件
$client->addFile(__DIR__ . '/test.jpg', 'file_field', 'test.jpg', 'image/jpeg');
$client->post('/upload');
WebSocket 支持
Swoole 协程客户端同样支持 WebSocket:
$client = new Client('127.0.0.1', 9502);
$client->upgrade('/');
$client->push('Hello WebSocket');
$response = $client->recv();
与其他库的对比
| 特性 | Swoole 协程 | Guzzle (同步) | Guzzle (异步 promise) | cURL 多线程 |
|---|---|---|---|---|
| 并发能力 | ✅ 原生并发 | ❌ 串行 | ✅ 依赖事件循环 | ✅ 需手动管理 |
| 并发上限 | 极高(10万+) | 受内存限制 | 有限制 | |
| 代码可读性 | 极好(同步风格) | 好 | 回调地狱 | 复杂 |
| 性能 | 极快 | 一般 | 较好 | 中等 |
| 依赖 | Swoole 扩展 | Composer 包 | Composer 包 | PHP 内置 |
在 Laravel / Symfony 中使用
如果你在框架中使用 Swoole,通常配合 LaravelS 或 Swoft 等适配器。
// 在 Laravel 控制器中
public function fetchData()
{
$https = new HttpsClient();
$results = \Swoole\Coroutine\run(function () {
$c1 = new HttpsClient('https://api1.com');
$c2 = new HttpsClient('https://api2.com');
// 并发执行
return [$c1->get('/data1'), $c2->get('/data2')];
});
return response()->json($results);
}
常见问题与优化
超时处理
$client->set(['timeout' => 5]); // 秒
错误重试
for ($retry = 0; $retry < 3; $retry++) {
$client->get('/');
if ($client->statusCode === 200) break;
\Swoole\Coroutine\System::sleep(1); // 协程休眠,不阻塞其他协程
}
内存管理
高并发时建议:
- 使用
Co::set(['max_coroutine' => 100000])限制协程数 - 及时关闭连接:
$client->close() - 使用
channel控制并发上限,避免内存爆炸
不依赖 Swoole 的纯 PHP 协程
如果你无法安装 Swoole,可以使用 ReactPHP 或 AMPHP 的协程(基于 Promise + Generator),但性能远不及 Swoole。
- Swoole 协程 HTTP 客户端是 PHP 中实现高并发 HTTP 请求的最佳方案。
- 它写法简单(同步风格),性能极高(原生并发)。
- 核心功能:并发请求、连接复用、WebSocket、文件上传。
- 结合 Channel 可以实现优雅的并发控制。
如果你的项目长期运行且需要高并发,强烈推荐使用 Swoole;如果是 FPM 短生命周期场景,还是用 Guzzle 等同步库更合适。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播