本文目录导读:

在 PHP 中实现 cURL 并发请求主要有以下几种方法,我来详细介绍:
*curlmulti 函数(最常用)**
这是 PHP 官方提供的并发处理方案:
<?php
// 准备多个请求
$urls = [
'https://api.example.com/users',
'https://api.example.com/posts',
'https://api.example.com/comments'
];
// 创建 cURL 多重句柄
$mh = curl_multi_init();
$handles = [];
// 为每个 URL 创建单独的 cURL 句柄
foreach ($urls as $key => $url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
// 添加到多重句柄
curl_multi_add_handle($mh, $ch);
$handles[$key] = $ch;
}
// 执行并发请求
$running = null;
do {
curl_multi_exec($mh, $running);
curl_multi_select($mh); // 等待活动连接
} while ($running > 0);
// 获取结果
$results = [];
foreach ($handles as $key => $ch) {
$results[$key] = curl_multi_getcontent($ch);
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
// 关闭多重句柄
curl_multi_close($mh);
// 输出结果
print_r($results);
?>
封装成可复用函数
<?php
/**
* 并发请求函数
* @param array $requests 请求配置数组
* @return array 响应结果
*/
function multiCurlRequest(array $requests) {
$mh = curl_multi_init();
$handles = [];
foreach ($requests as $key => $request) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $request['url']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 设置请求方法
$method = isset($request['method']) ? strtoupper($request['method']) : 'GET';
if ($method === 'POST') {
curl_setopt($ch, CURLOPT_POST, true);
if (isset($request['post_data'])) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $request['post_data']);
}
}
// 设置请求头
if (isset($request['headers'])) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $request['headers']);
}
// 设置超时
$timeout = isset($request['timeout']) ? $request['timeout'] : 30;
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
// 是否SSL验证
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_multi_add_handle($mh, $ch);
$handles[$key] = $ch;
}
// 执行并发请求
$running = null;
do {
$status = curl_multi_exec($mh, $running);
if ($running) {
curl_multi_select($mh);
}
} while ($running > 0 && $status === CURLM_OK);
// 收集结果
$results = [];
foreach ($handles as $key => $ch) {
$results[$key] = [
'content' => curl_multi_getcontent($ch),
'error' => curl_error($ch),
'errno' => curl_errno($ch),
'info' => curl_getinfo($ch)
];
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
curl_multi_close($mh);
return $results;
}
// 使用示例
$requests = [
'user' => [
'url' => 'https://api.example.com/user/1',
'method' => 'GET',
'timeout' => 10
],
'post' => [
'url' => 'https://api.example.com/post/create',
'method' => 'POST',
'post_data' => ['title' => 'Hello', 'content' => 'World'],
'timeout' => 15
],
'search' => [
'url' => 'https://api.example.com/search?q=php',
'method' => 'GET',
'headers' => ['Authorization: Bearer token']
]
];
$results = multiCurlRequest($requests);
foreach ($results as $key => $result) {
echo "请求 {$key} 结果:\n";
echo "状态码: " . $result['info']['http_code'] . "\n";
echo "内容: " . $result['content'] . "\n\n";
}
?>
使用生成器模式(PHP 5.5+)
<?php
// 使用 Generator 处理流式响应
class MultiCurlHandler {
private $mh;
private $channels = [];
public function __construct() {
$this->mh = curl_multi_init();
}
public function addRequest($name, $url, $options = []) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
foreach ($options as $opt => $value) {
curl_setopt($ch, $opt, $value);
}
curl_multi_add_handle($this->mh, $ch);
$this->channels[$name] = $ch;
return $this;
}
public function execute() {
$running = null;
do {
curl_multi_exec($this->mh, $running);
curl_multi_select($this->mh);
} while ($running > 0);
$results = [];
foreach ($this->channels as $name => $ch) {
$results[$name] = curl_multi_getcontent($ch);
curl_multi_remove_handle($this->mh, $ch);
curl_close($ch);
}
curl_multi_close($this->mh);
return $results;
}
}
// 使用
$handler = new MultiCurlHandler();
$handler->addRequest('google', 'https://www.google.com')
->addRequest('baidu', 'https://www.baidu.com')
->addRequest('github', 'https://api.github.com');
$results = $handler->execute();
print_r($results);
?>
使用 Guzzle 库(推荐)
如果允许使用第三方库,Guzzle 提供了更优雅的方式:
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
$client = new Client(['timeout' => 10]);
// 创建多个请求
$promises = [
'users' => $client->getAsync('https://api.example.com/users'),
'posts' => $client->getAsync('https://api.example.com/posts'),
'comments' => $client->getAsync('https://api.example.com/comments'),
];
// 等待所有请求完成
$results = Promise\Utils::settle($promises)->wait();
// 处理结果
foreach ($results as $key => $result) {
if ($result['state'] === 'fulfilled') {
echo "{$key}: " . $result['value']->getBody() . "\n";
} else {
echo "{$key} 失败: " . $result['reason'] . "\n";
}
}
?>
处理动态添加请求
<?php
// 分批处理大量请求
function processManyRequests(array $urls, $batchSize = 10) {
$allResults = [];
foreach (array_chunk($urls, $batchSize) as $batch) {
$mh = curl_multi_init();
$handles = [];
foreach ($batch as $key => $url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($mh, $ch);
$handles[$key] = $ch;
}
$running = null;
do {
curl_multi_exec($mh, $running);
curl_multi_select($mh);
} while ($running > 0);
foreach ($handles as $key => $ch) {
$allResults[$key] = curl_multi_getcontent($ch);
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
curl_multi_close($mh);
}
return $allResults;
}
?>
注意事项
- 超时设置:一定要设置超时,避免请求无限等待
- 错误处理:检查
curl_error()确保请求成功 - 资源清理:使用完要关闭所有句柄
- 限制并发数:避免一次性发起过多请求
- SSL 验证:生产环境建议启用 SSL 验证
选择哪种方式取决于你的需求和项目环境,如果是新项目,推荐使用 Guzzle;如果不想引入依赖,使用 curlmulti* 就足够了。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播