PHP curl_multi_errno 函数
最后修改日期:2025 年 4 月 11 日
PHP curl_multi_errno 函数返回 cURL multi handle 的最后一个错误号。它用于识别异步 cURL 操作中的错误。此函数有助于诊断并行 HTTP 请求中的问题。
基本定义
curl_multi_errno 函数返回一个包含 cURL multi handle 最后一个错误号的整数。如果没有发生错误,它返回 0 (CURLM_OK)。
语法:curl_multi_errno(CurlMultiHandle $multi_handle): int。multi handle 必须使用 curl_multi_init() 创建。始终在 multi 操作后检查此项以检测潜在问题。
基本的 Multi Handle 错误检查
此示例演示了在初始化 multi handle 后检查错误。
<?php
declare(strict_types=1);
$mh = curl_multi_init();
if ($mh === false) {
die("Failed to initialize multi handle");
}
$errno = curl_multi_errno($mh);
if ($errno !== CURLM_OK) {
echo "Multi handle error: " . curl_multi_strerror($errno);
} else {
echo "Multi handle initialized successfully";
}
curl_multi_close($mh);
此代码初始化一个 cURL multi handle 并检查错误。我们使用 curl_multi_strerror 获取人类可读的错误消息。该示例展示了 multi handle初始化的基本错误处理。
Multi 执行中的错误处理
此示例展示了如何在 multi handle 执行期间检查错误。
<?php
declare(strict_types=1);
$urls = [
"https://example.com",
"https://nonexistent.example",
"https://another.example"
];
$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);
$errno = curl_multi_errno($mh);
if ($errno !== CURLM_OK) {
echo "Multi error: " . curl_multi_strerror($errno);
break;
}
usleep(10000);
} while ($active && $status === CURLM_OK);
foreach ($handles as $ch) {
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
curl_multi_close($mh);
我们创建多个 cURL handle 并将它们添加到 multi handle 中。在执行期间,我们使用 curl_multi_errno 持续检查错误。如果发生错误,循环会中断,从而阻止进一步执行有问题的请求。
处理特定的错误代码
此示例演示了如何处理 curl_multi_errno 的特定错误代码。
<?php
declare(strict_types=1);
$mh = curl_multi_init();
// Intentionally cause an error by adding a non-curl handle
$fakeHandle = fopen('php://temp', 'r');
curl_multi_add_handle($mh, $fakeHandle);
$errno = curl_multi_errno($mh);
switch ($errno) {
case CURLM_OK:
echo "No error occurred";
break;
case CURLM_BAD_HANDLE:
echo "Error: Invalid multi handle (CURLM_BAD_HANDLE)";
break;
case CURLM_BAD_EASY_HANDLE:
echo "Error: Invalid easy handle (CURLM_BAD_EASY_HANDLE)";
break;
case CURLM_OUT_OF_MEMORY:
echo "Error: Out of memory (CURLM_OUT_OF_MEMORY)";
break;
case CURLM_INTERNAL_ERROR:
echo "Error: Internal error (CURLM_INTERNAL_ERROR)";
break;
default:
echo "Unknown error occurred: $errno";
}
if (is_resource($fakeHandle)) {
fclose($fakeHandle);
}
curl_multi_close($mh);
我们通过将非 cURL handle 添加到 multi handle 中来故意引起错误。然后代码检查特定的错误代码并提供适当的处理。这演示了如何对各种 cURL multi 错误做出不同的响应。
并行请求中的错误处理
此示例展示了并行请求的全面错误处理。
<?php
declare(strict_types=1);
$urls = [
"https://valid.example.com",
"https://invalid.example",
"https://timeout.example.com"
];
$mh = curl_multi_init();
$handles = [];
foreach ($urls as $i => $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_multi_add_handle($mh, $ch);
$handles[$i] = $ch;
}
$active = null;
do {
$mrc = curl_multi_exec($mh, $active);
if ($mrc !== CURLM_OK) {
$errno = curl_multi_errno($mh);
echo "Multi error: " . curl_multi_strerror($errno);
break;
}
// Check for individual handle errors
while ($info = curl_multi_info_read($mh)) {
if ($info['result'] !== CURLE_OK) {
$handle = $info['handle'];
$errno = curl_errno($handle);
echo "Handle error: " . curl_strerror($errno) . "\n";
}
}
usleep(10000);
} while ($active);
foreach ($handles as $ch) {
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
curl_multi_close($mh);
此示例执行带有全面错误处理的并行请求。我们同时检查 multi handle 错误和单个 handle 错误。代码演示了如何处理在并行执行期间可能发生的各种类型的错误。
与 curl_multi_strerror 结合使用
此示例展示了如何将 curl_multi_errno 与 curl_multi_strerror 结合使用。
<?php
declare(strict_types=1);
function executeMultiRequests(array $urls): void {
$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;
}
$active = null;
do {
$status = curl_multi_exec($mh, $active);
if ($status !== CURLM_OK) {
$errno = curl_multi_errno($mh);
$errorMsg = curl_multi_strerror($errno);
throw new RuntimeException("cURL multi error: $errorMsg ($errno)");
}
usleep(10000);
} while ($active);
foreach ($handles as $ch) {
$content = curl_multi_getcontent($ch);
echo "Content length: " . strlen($content) . "\n";
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
curl_multi_close($mh);
}
try {
executeMultiRequests([
"https://example.com",
"https://example.org"
]);
} catch (RuntimeException $e) {
echo "Error: " . $e->getMessage();
}
我们将 multi handle 操作包装在一个在出错时抛出异常的函数中。curl_multi_strerror 提供了一个人类可读的错误消息。这种方法为复杂的 multi 请求场景创建了更清晰的错误处理。
最佳实践
- 操作后检查:始终在 multi handle 操作后检查 curl_multi_errno。
- 与 strerror 结合:使用 curl_multi_strerror 获取可读的错误消息。
- 处理特定代码:为不同的错误代码实现特定的处理。
- 清理资源:始终移除 handle 并关闭 multi handle。
- 检查单个 handle:也要检查单个 easy handle 中的错误。
来源
本教程介绍了 PHP curl_multi_errno 函数,并通过实际示例展示了其在并行 cURL 操作错误处理中的用法。