PHP curl_multi_getcontent 函数
最后修改日期:2025 年 4 月 11 日
PHP curl_multi_getcontent 函数在使用 multi 接口时,用于从 cURL 句柄中检索内容。它用于在执行多个并行 cURL 请求后获取响应数据。
基本定义
如果设置了 CURLOPT_RETURNTRANSFER,curl_multi_getcontent 函数将返回 cURL 句柄的内容。它与 cURL multi 接口配合用于并行请求。
语法:curl_multi_getcontent(CurlHandle $handle): ?string。句柄必须是 multi 句柄执行的一部分。如果没有可用内容则返回 NULL,失败则返回 FALSE。
基础多请求
此示例演示了发出两个并行请求并获取其内容。
<?php
declare(strict_types=1);
$urls = [
"https://jsonplaceholder.typicode.com/posts/1",
"https://jsonplaceholder.typicode.com/posts/2"
];
$mh = curl_multi_init();
$handles = [];
foreach ($urls as $url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($mh, $ch);
$handles[] = $ch;
}
$running = null;
do {
curl_multi_exec($mh, $running);
} while ($running);
foreach ($handles as $ch) {
$content = curl_multi_getcontent($ch);
echo $content . "\n";
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
curl_multi_close($mh);
此代码创建了两个并行请求来获取帖子。我们使用 curl_multi_exec 同时处理它们。执行后,我们使用 curl_multi_getcontent 检索每个响应。始终正确清理句柄。
处理多个 JSON 响应
此示例展示了如何处理并行请求的多个 JSON 响应。
<?php
declare(strict_types=1);
$userIds = [1, 2, 3];
$mh = curl_multi_init();
$handles = [];
foreach ($userIds as $id) {
$url = "https://jsonplaceholder.typicode.com/users/{$id}";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($mh, $ch);
$handles[$id] = $ch;
}
$running = null;
do {
curl_multi_exec($mh, $running);
} while ($running);
$results = [];
foreach ($handles as $id => $ch) {
$content = curl_multi_getcontent($ch);
$results[$id] = json_decode($content, true);
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
curl_multi_close($mh);
print_r($results);
我们并行获取三个用户记录。每个响应都从 JSON 解码并存储在一个数组中。结果与原始用户 ID 保持关联。这展示了高效的 API 数据批量处理。
多请求中的错误处理
此示例演示了多个 cURL 请求的正确错误处理。
<?php
declare(strict_types=1);
$urls = [
"https://jsonplaceholder.typicode.com/posts/1",
"https://invalid.url",
"https://jsonplaceholder.typicode.com/comments/1"
];
$mh = curl_multi_init();
$handles = [];
foreach ($urls as $i => $url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_multi_add_handle($mh, $ch);
$handles[$i] = $ch;
}
$running = null;
do {
curl_multi_exec($mh, $running);
} while ($running);
foreach ($handles as $i => $ch) {
$content = curl_multi_getcontent($ch);
$error = curl_error($ch);
if ($error) {
echo "Request {$i} failed: {$error}\n";
} else {
echo "Request {$i} succeeded:\n";
echo substr($content, 0, 100) . "...\n";
}
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
curl_multi_close($mh);
我们处理三个 URL,其中一个 URL 被故意设为无效。对于每个请求,我们使用 curl_error 检查错误。该示例展示了如何在批量操作中处理成功和失败的请求。
为多请求设置自定义选项
此示例展示了如何为批量中的每个请求设置不同的选项。
<?php
declare(strict_types=1);
$requests = [
[
'url' => 'https://jsonplaceholder.typicode.com/posts/1',
'method' => 'GET'
],
[
'url' => 'https://jsonplaceholder.typicode.com/posts',
'method' => 'POST',
'data' => ['title' => 'foo', 'body' => 'bar', 'userId' => 1]
]
];
$mh = curl_multi_init();
$handles = [];
foreach ($requests as $req) {
$ch = curl_init($req['url']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if ($req['method'] === 'POST') {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req['data']);
}
curl_multi_add_handle($mh, $ch);
$handles[] = $ch;
}
$running = null;
do {
curl_multi_exec($mh, $running);
} while ($running);
foreach ($handles as $i => $ch) {
$content = curl_multi_getcontent($ch);
echo "Response {$i}:\n";
echo $content . "\n\n";
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
curl_multi_close($mh);
我们并行执行 GET 和 POST 请求。在将每个句柄添加到 multi 句柄之前,都会配置其特定选项。这显示了 multi 接口对于不同请求类型的灵活性。
处理大量请求
此示例演示了如何高效地处理大量批量请求。
<?php
declare(strict_types=1);
// Generate 10 URLs to fetch
$urls = array_map(
fn($id) => "https://jsonplaceholder.typicode.com/posts/{$id}",
range(1, 10)
);
$mh = curl_multi_init();
$handles = [];
$results = [];
$concurrency = 5; // Process 5 at a time
foreach ($urls as $i => $url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_multi_add_handle($mh, $ch);
$handles[$i] = $ch;
// Process in batches to avoid overwhelming the system
if (count($handles) % $concurrency === 0) {
$running = null;
do {
curl_multi_exec($mh, $running);
} while ($running);
// Process completed requests
foreach ($handles as $j => $ch) {
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200) {
$results[$j] = curl_multi_getcontent($ch);
}
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
$handles = [];
}
}
// Process any remaining handles
if (!empty($handles)) {
$running = null;
do {
curl_multi_exec($mh, $running);
} while ($running);
foreach ($handles as $j => $ch) {
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200) {
$results[$j] = curl_multi_getcontent($ch);
}
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
}
curl_multi_close($mh);
echo "Fetched " . count($results) . " responses\n";
此示例以 5 个为一批处理 10 个 URL,以更好地管理资源。我们在存储结果之前检查 HTTP 状态码。该方法可防止在处理大量请求时出现系统过载。结果保持其原始顺序,方便参考。
最佳实践
- 批量大小:限制并发请求以避免系统过载。
- 错误处理:同时检查 curl_multi_getcontent 和 curl_error。
- 资源清理:始终正确移除和关闭句柄。
- 超时:为每个句柄设置 CURLOPT_TIMEOUT。
- 内存:对大型操作分批处理响应。
来源
本教程涵盖了 PHP curl_multi_getcontent 函数,并通过实际示例展示了其在并行 HTTP 请求处理中的用法。