PHP curl_multi_info_read 函数
最后修改日期:2025 年 4 月 11 日
PHP curl_multi_info_read 函数读取已完成 cURL 操作的信息。它与 curl_multi_exec 一起用于并行处理多个传输。此函数有助于跟踪已完成的请求。
基本定义
curl_multi_info_read 函数从 multi handle 读取已完成传输的信息。它返回一个信息数组或 FALSE。
语法:curl_multi_info_read(CurlMultiHandle $multi_handle, int &$queued_messages = null): array|false。必须反复调用该函数,直到它返回 FALSE。
基础多请求
此示例演示了如何并行执行多个 cURL 请求。
<?php
declare(strict_types=1);
$urls = [
"https://jsonplaceholder.typicode.com/posts/1",
"https://jsonplaceholder.typicode.com/posts/2",
"https://jsonplaceholder.typicode.com/posts/3"
];
$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;
}
do {
$status = curl_multi_exec($mh, $active);
if ($active) {
curl_multi_select($mh);
}
} while ($active && $status == CURLM_OK);
while ($info = curl_multi_info_read($mh)) {
$ch = $info['handle'];
$content = curl_multi_getcontent($ch);
echo "Completed request: " . curl_getinfo($ch, CURLINFO_EFFECTIVE_URL) . "\n";
echo "Status: " . $info['result'] . "\n";
echo "Response length: " . strlen($content) . " bytes\n\n";
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
curl_multi_close($mh);
此代码并行执行三个请求。我们使用 curl_multi_info_read 来获取已完成请求的信息。结果包含 handle 和状态码。处理后我们会清理 handle。
处理多个请求中的错误
此示例展示了在处理多个请求时如何处理错误。
<?php
declare(strict_types=1);
$urls = [
"https://jsonplaceholder.typicode.com/posts/1",
"https://invalid.url.xyz",
"https://jsonplaceholder.typicode.com/posts/3"
];
$mh = curl_multi_init();
$handles = [];
foreach ($urls as $url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_multi_add_handle($mh, $ch);
$handles[$url] = $ch;
}
do {
$status = curl_multi_exec($mh, $active);
if ($active) {
curl_multi_select($mh);
}
} while ($active && $status == CURLM_OK);
while ($info = curl_multi_info_read($mh)) {
$ch = $info['handle'];
$url = array_search($ch, $handles, true);
if ($info['result'] !== CURLE_OK) {
echo "Error for $url: " . curl_error($ch) . "\n";
} else {
$content = curl_multi_getcontent($ch);
echo "Success for $url: " . strlen($content) . " bytes\n";
}
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
curl_multi_close($mh);
我们处理包括无效 URL 在内的多个 URL。info 数组包含一个我们检查错误的返回码。对于失败的请求,我们输出错误消息。成功的请求显示响应长度。
使用回调处理响应
此示例演示了如何使用回调来处理已完成的请求。
<?php
declare(strict_types=1);
function process_response(array $info, $content) {
$url = curl_getinfo($info['handle'], CURLINFO_EFFECTIVE_URL);
$code = curl_getinfo($info['handle'], CURLINFO_HTTP_CODE);
echo "URL: $url\n";
echo "Status: $code\n";
echo "Content length: " . strlen($content) . "\n";
echo "cURL result: " . $info['result'] . "\n\n";
}
$urls = [
"https://jsonplaceholder.typicode.com/posts/1",
"https://jsonplaceholder.typicode.com/posts/2",
"https://jsonplaceholder.typicode.com/posts/3"
];
$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;
}
do {
$status = curl_multi_exec($mh, $active);
if ($active) {
curl_multi_select($mh);
}
} while ($active && $status == CURLM_OK);
while ($info = curl_multi_info_read($mh)) {
$content = curl_multi_getcontent($info['handle']);
process_response($info, $content);
curl_multi_remove_handle($mh, $info['handle']);
curl_close($info['handle']);
}
curl_multi_close($mh);
我们定义了一个回调函数来处理每个已完成的请求。回调接收 info 数组和响应内容。这种方法有助于组织复杂的响应处理逻辑。处理后会执行清理。
跟踪多个请求的进度
此示例展示了如何在执行多个请求时跟踪进度。
<?php
declare(strict_types=1);
$urls = [
"https://jsonplaceholder.typicode.com/posts/1",
"https://jsonplaceholder.typicode.com/posts/2",
"https://jsonplaceholder.typicode.com/posts/3"
];
$mh = curl_multi_init();
$handles = [];
$completed = 0;
$total = count($urls);
foreach ($urls as $url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_NOPROGRESS, false);
curl_multi_add_handle($mh, $ch);
$handles[] = $ch;
}
do {
$status = curl_multi_exec($mh, $active);
// Check for completed requests
while ($info = curl_multi_info_read($mh)) {
$completed++;
echo "Completed $completed of $total requests\n";
curl_multi_remove_handle($mh, $info['handle']);
curl_close($info['handle']);
}
if ($active) {
curl_multi_select($mh);
}
} while ($active && $status == CURLM_OK);
curl_multi_close($mh);
echo "All requests completed\n";
我们在执行过程中跟踪已完成请求的数量。在循环中调用 info_read 函数来检测完成情况。这提供了关于进度的实时反馈。总数有助于用户了解完成情况。
处理大量请求
此示例演示了如何高效地处理大量请求。
<?php
declare(strict_types=1);
// Generate 100 sample URLs
$urls = array_map(function($i) {
return "https://jsonplaceholder.typicode.com/posts/" . ($i + 1);
}, range(0, 99));
$mh = curl_multi_init();
$handles = [];
$batchSize = 10;
$results = [];
// Process in batches to avoid overwhelming the system
for ($i = 0; $i < count($urls); $i += $batchSize) {
$batch = array_slice($urls, $i, $batchSize);
// Add batch to multi handle
foreach ($batch as $url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($mh, $ch);
$handles[$url] = $ch;
}
// Execute batch
do {
$status = curl_multi_exec($mh, $active);
if ($active) {
curl_multi_select($mh);
}
} while ($active && $status == CURLM_OK);
// Process completed requests
while ($info = curl_multi_info_read($mh)) {
$ch = $info['handle'];
$url = array_search($ch, $handles, true);
$results[$url] = [
'status' => $info['result'],
'content' => curl_multi_getcontent($ch)
];
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
unset($handles[$url]);
}
}
curl_multi_close($mh);
echo "Processed " . count($results) . " requests\n";
echo "Success rate: " .
(count(array_filter($results, fn($r) => $r['status'] === CURLE_OK)) /
count($results) * 100 . "%\n";
我们将 100 个请求分批处理,每批 10 个,以更好地管理资源。在移至下一批之前,我们会执行和处理每一批。结果会存储以供后续分析。这种方法可以防止大型请求集导致系统过载。
最佳实践
- 错误检查:始终检查 info 数组中的返回码。
- 资源清理:处理后移除并关闭 handle。
- 批量处理:将大型请求集分批处理。
- 进度反馈:为长时间操作提供进度更新。
- 内存管理:及时释放资源以避免泄漏。
来源
本教程通过实际示例介绍了 PHP curl_multi_info_read 函数,展示了并行请求处理和结果处理。