我试图检测cURL请求何时超时。如果这有所不同,我使用curl_multi_exec吗?
curl_errno()的输出为0,表明它是成功的。但是curl_error()的输出是:
操作在1435毫秒后超时,0个-1个字节 接收
任何想法为什么错误代码是好的,但错误信息存在?对于超时,我希望错误代码为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);
}
答案 0 :(得分:2)
使用curl_multi_exec()
时,您需要使用curl_multi_info_read()
来获取特定句柄的错误代码。这是由于PHP在简单和多个接口中与cURL接口的方式,以及如何从cURL的curl_multi_info_read()函数中获取错误代码(参见下面的解释)。
基本上,如果您使用多个句柄,则调用curl_errno()
和curl_error()
不可靠或准确。
请参阅manual:
中的此修改示例<?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]);
}
输出:
http://www.cnn.com/返回代码0
http://wijgeiwojgieowjg.com/返回了代码6
http://www.example.com/返回了代码28
<强>解释强>
具体来说,这是由于PHP curl_exec()
调用cURL&#39; curl_easy_perform
返回CURLcode(错误代码)并且PHP指定cURL选项CURLOPT_ERRORBUFFER这会导致缓冲区自动填充错误消息(如果发生)。
但是当使用PHP curl_multi_exec()
时,PHP会调用cURL&#39; curl_multi_perform
,它会立即返回,并且不会返回多句柄的错误代码。您必须调用cURL的curl_multi_info_read
函数来获取各个句柄的错误代码。
PHP 5.5.0为cURL的curl_easy_strerror()
提供了一个包装器,它返回一个与卷曲错误代码相对应的字符串。
答案 1 :(得分:0)
调试真的很令人沮丧,因为php.net上的文档和示例与异步卷曲相关性很差。
以下是一些示例代码,可帮助演示curl_multi_exec中的DOES工作原理:
// Main work loop
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
while($status = curl_multi_info_read($mh)) {
if($status['msg'] == CURLMSG_DONE) {
$errno = $status['result'];
$errstr = curl_strerror($errno);
if($errno == CURLE_OK) {
// This request completed successfully
// Do something with the info
$info = curl_getinfo($status['handle');
} else {
// There was an error handling this request,
// like a timeout or something.
// Note: curl_errno($ch) will probably say success
// but it's lying to you. Ignore it.
fwrite(STDERR, "Request failed: Error($errno): $errstr\n");
}
}
}
通过上面的主要工作循环,您可以根据需要多次调用它。像
这样的东西while($this->workRemaining()) {
$this->work();
usleep(100); // Sleep, or better yet do something productive
}
我不打算打印全班。你可以做它想做的事。
重要的是检查$status['result']
以确定是否有错误。永远不要依赖curl_getinfo($ch)
,因为它在multi_curl环境中是错误的。