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 操作错误处理中的用法。