[英]Detect cURL timeout in PHP
我正試圖檢測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);
}
使用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]);
}
輸出:
http://www.cnn.com/返回代碼0
http://wijgeiwojgieowjg.com/返回代碼6
http://www.example.com/返回代碼28
說明:
具體來說,這是由於PHP的curl_exec()
調用cURL的curl_easy_perform
返回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錯誤代碼的字符串。
這可能是非常令人沮喪的調試,因為php.net上的文檔和示例與async curl相關性很差。
下面是一些示例代碼,以幫助演示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環境中是錯誤的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.