检测 PHP 中的 cURL 超时

Kit*_*Kit 6 php curl

我试图检测 cURL 请求何时超时。如果这有区别,我正在使用 curl_multi_exec 吗?

curl_errno() 的输出为 0,这表明它是成功的。但是 curl_error() 的输出是:

操作在 1435 毫秒后超时,收到 -1 个字节中的 0 个

任何想法为什么错误代码是好的,但错误消息存在?我希望超时的错误代码为 28。

另外,有什么我可以在 curl_getinfo() 中检查超时的吗?

我使用的是 PHP 5.4.4/cURL 7.24.0。

编辑 1 - 示例代码:

$mh = curl_multi_init();
curl_multi_add_handle($mh,$a);
curl_multi_add_handle($mh,$b);
curl_multi_add_handle($mh,...);

do {
    $mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active && $mrc == CURLM_OK) {
    if (curl_multi_select($mh) == -1) usleep(100);
    do { $mrc = curl_multi_exec($mh, $active); }
    while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
Run Code Online (Sandbox Code Playgroud)

dre*_*010 4

使用 时curl_multi_exec(),您需要使用curl_multi_info_read()来获取特定句柄的错误代码。这是由于 PHP 在其简单且多个接口中与 cURL 交互的方式,以及如何从 cURL 的curl_multi_info_read()函数的各个句柄上获取错误代码(请参见下面的说明)。

基本上,如果您使用多句柄,则调用curl_errno()并不curl_error()可靠或不准确。

请参阅手册中的修改示例:

<?php

$urls = array(
   "http://www.cnn.com/",
   "http://www.bbc.co.uk/",
   "http://www.yahoo.com/",
   'http://wijgeiwojgieowjg.com/',
   'http://www.example.com/',
);

$infos = array();

$mh = curl_multi_init();

foreach ($urls as $i => $url) {
    $conn[$i] = curl_init($url);
    curl_setopt($conn[$i], CURLOPT_RETURNTRANSFER, 1);

    if (strpos($url, 'example.com') !== false) {
        // set a really short timeout for one url
        curl_setopt($conn[$i], CURLOPT_TIMEOUT_MS, 10);
    }

    curl_multi_add_handle($mh, $conn[$i]);
}

do {
    $status = curl_multi_exec($mh, $active);

    if (($info = curl_multi_info_read($mh)) !== false) {
        $infos[$info['handle']] = $info;
    }

} while ($status === CURLM_CALL_MULTI_PERFORM || $active);

foreach ($urls as $i => $url) {
    $info = $infos[$conn[$i]];

    echo "$url returned code {$info['result']}";
    if (version_compare(PHP_VERSION, '5.5.0') >= 0) {
        echo ": " . curl_strerror($info['result']);
    }
    echo "\n";

    if ($info['result'] === 0) {
        $res[$i] = curl_multi_getcontent($conn[$i]);
    }

    curl_close($conn[$i]);
}
Run Code Online (Sandbox Code Playgroud)

输出:

http://www.cnn.com/返回代码 0

http://www.bbc.co.uk/返回代码 0

http://www.yahoo.com/返回代码 0

http://wijgeiwojgieowjg.com/返回代码 6

http://www.example.com/返回代码 28

解释:

具体来说,这是由于 PHPcurl_exec()调用 cURL 的方式造成的curl_easy_perform,cURL 返回 CURLcode(错误代码),并且 PHP 指定 cURL 选项CURLOPT_ERRORBUFFER,这会导致缓冲区在发生错误时自动填充错误消息。

但是,当使用 PHP 时curl_multi_exec(),PHP 调用 cURL curl_multi_perform,它会立即返回,并且不会返回多句柄的错误代码。您必须调用 cURL 的curl_multi_info_read函数来获取各个句柄的错误代码。

PHP 5.5.0 为 cURL 提供了一个包装器curl_easy_strerror(),它返回与curl 错误代码相对应的字符串。