我试图检测 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)
使用 时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 错误代码相对应的字符串。