关于php是如何并行异步处理HTTP请求的这件事
在 PHP 中,由于其传统的同步阻塞模型,实现并行异步处理 HTTP 请求并不像其他语言(如 Go 或 Node.js)那样直接。#
不过,仍然可以通过一些扩展和工具来实现并行异步处理。以下是几种常见的方法:#
1. 使用 cURL 的多线程功能#
PHP 提供了
curl_multi_*
系列函数,用于实现 cURL 的多线程功能。<?php
function curlMultiRequest(array $urls) {
$curlHandles = [];
foreach ($urls as $url) {
$curlHandles[] = curl_init($url);
curl_setopt($curlHandles[count($curlHandles) - 1], CURLOPT_RETURNTRANSFER, true);
}
$multiHandle = curl_multi_init();
foreach ($curlHandles as $handle) {
curl_multi_add_handle($multiHandle, $handle);
}
$active = null;
do {
$status = curl_multi_exec($multiHandle, $active);
curl_multi_select($multiHandle);
} while ($active && $status == CURLM_OK);
$results = [];
foreach ($curlHandles as $handle) {
$results[] = curl_multi_getcontent($handle);
curl_multi_remove_handle($multiHandle, $handle);
curl_close($handle);
}
curl_multi_close($multiHandle);
return $results;
}
// 示例用法
$urls = ['https://api.example.com/data1', 'https://api.example.com/data2'];
$results = curlMultiRequest($urls);
foreach ($results as $result) {
echo $result . "\n";
}
2. 使用 Guzzle 异步客户端#
Guzzle 是一个 PHP HTTP 客户端,支持异步请求。以下是示例代码:
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
$client = new Client();
$urls = ['https://api.example.com/data1', 'https://api.example.com/data2'];
$promises = [];
foreach ($urls as $url) {
$promises[] = $client->getAsync($url);
}
$results = [];
foreach (GuzzleHttp\Promise\settle($promises)->wait() as $result) {
if ($result['state'] === 'fulfilled') {
$results[] = $result['value']->getBody()->getContents();
}
}
foreach ($results as $result) {
echo $result . "\n";
}
3. 使用 Swoole 扩展#
Swoole 是一个高性能的 PHP 扩展,支持协程和异步 IO。以下是示例代码:
<?php
// 确保 Swoole 扩展已安装
if (!extension_loaded('swoole')) {
die('Swoole extension is not installed.');
}
use Swoole\Coroutine;
use Swoole\Coroutine\Http\Client;
Coroutine\run(function () {
$urls = ['https://api.example.com/data1', 'https://api.example.com/data2'];
$tasks = [];
foreach ($urls as $url) {
$tasks[] = Coroutine::create(function () use ($url) {
$client = new Client('api.example.com', 443);
$client->set(['timeout' => 1]);
$client->get($url);
return $client->body;
});
}
foreach ($tasks as $task) {
echo Coroutine::yield($task) . "\n";
}
});
4. 使用 ReactPHP#
ReactPHP 是一个事件驱动的非阻塞 PHP 框架,支持异步 HTTP 请求。以下是示例代码:
<?php
require 'vendor/autoload.php';
use React\EventLoop\Factory;
use React\HttpClient\Client;
$loop = Factory::create();
$client = new Client($loop);
$urls = ['https://api.example.com/data1', 'https://api.example.com/data2'];
$requests = [];
foreach ($urls as $url) {
$requests[] = $client->get($url);
}
$loop->addTimer(0, function () use ($requests, $loop) {
foreach ($requests as $request) {
$request->on('response', function ($response) {
$response->on('data', function ($data) {
echo $data;
});
});
}
});
$loop->run();
5. 使用 pcntl 多进程#
pcntl 扩展允许 PHP 使用多进程编程。以下是示例代码:
<?php
$urls = ['https://api.example.com/data1', 'https://api.example.com/data2'];
$processes = [];
foreach ($urls as $url) {
$pid = pcntl_fork();
if ($pid == -1) {
die('Could not fork process');
} elseif ($pid == 0) {
// 子进程
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response . "\n";
exit(0);
} else {
// 父进程
$processes[] = $pid;
}
}
// 父进程等待所有子进程结束
foreach ($processes as $pid) {
pcntl_waitpid($pid, $status);
}
总结#
-
cURL 多线程:适用于简单的并发请求,使用
curl_multi_*
函数。 -
Guzzle 异步客户端:适用于需要更高级功能的 HTTP 请求,支持异步和同步请求。
-
Swoole 扩展:适用于高性能的异步和协程编程,支持异步 IO 和协程。
-
ReactPHP:适用于事件驱动的异步编程,支持异步 HTTP 请求。
-
pcntl 多进程:适用于需要多进程处理的任务,使用
pcntl_fork
创建子进程。
作者:Carver-大脸猫
出处:https://www.cnblogs.com/carver/articles/18728881
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
转载请注明原处
本文来自博客园,作者:Carver-大脸猫,转载请注明原文链接:https://www.cnblogs.com/carver/articles/18728881
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现