![](/img/trans.png)
[英]PHP cURL: CURLOPT_CONNECTTIMEOUT vs CURLOPT_TIMEOUT
[英]PHP Catch cURL CURLOPT_TIMEOUT and CURLOPT_CONNECTTIMEOUT events and take action
我想在檢測到CURLOPT_CONNECTTIMEOUT和CURLOPT_TIMEOUT時檢測,捕獲並執行某些操作。
我該怎么做呢 ?
我有以下標題:
public static $userAgents = array(
'FireFox3' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9) Gecko/2008052906 Firefox/3.0',
'GoogleBot' => 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)',
'IE7' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)',
'Netscape' => 'Mozilla/4.8 [en] (Windows NT 6.0; U)',
'Opera' => 'Opera/9.25 (Windows NT 6.0; U; en)'
);
public static $options = array(
CURLOPT_USERAGENT => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)',
CURLOPT_AUTOREFERER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FRESH_CONNECT => true,
CURLOPT_COOKIEJAR => "cookies.txt",
CURLOPT_COOKIEFILE => "cookies.txt",
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 300,
//CURLOPT_COOKIESESSION => false,
);
以及下面的函數,其中$ res是一個包含html文件名的數組
public function multiCurl($res, $options = "") {
if (count($res) <= 0)
return False;
$handles = array();
if (!$options) // add default options
$options = self::$options;
// add curl options to each handle
foreach ($res as $k => $row) {
$ch{$k} = curl_init();
$options[CURLOPT_URL] = $row['url'];
curl_setopt_array($ch{$k}, $options);
$handles[$k] = $ch{$k};
}
$mh = curl_multi_init();
foreach ($handles as $k => $handle) {
curl_multi_add_handle($mh, $handle);
}
$running_handles = null;
//execute the handles
do {
$status_cme = curl_multi_exec($mh, $running_handles);
} while ($cme == CURLM_CALL_MULTI_PERFORM);
while ($running_handles && $status_cme == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$status_cme = curl_multi_exec($mh, $running_handles);
} while ($status == CURLM_CALL_MULTI_PERFORM);
}
}
foreach ($res as $k => $row) {
$res[$k]['error'] = curl_error($handles[$k]);
if (!empty($res[$k]['error']))
$res[$k]['data'] = '';
else {
//$res[$k]['data'] = curl_multi_getcontent($handles[$k]); // get results
file_put_contents(CRAWLER_FILES . $k . '.html', curl_multi_getcontent($handles[$k]));
}
// close current handler
curl_multi_remove_handle($mh, $handles[$k]);
}
curl_multi_close($mh);
return $res; // return response
}
要獲取有關請求的信息,您可以查看curl_getinfo
或curl_multi_info_read
並使用類似它的東西:
curl_exec($ch);
if(!curl_errno($ch))
{
$info = curl_getinfo($ch);
echo 'Took ' . $info['total_time'] . ' seconds to send a request to ' . $info['url'];
}
在信息數組中,您可以接收以下數據:
你有2個選擇:
curl_getinfo($ch)
返回的數組中,將connect_time
與您用於CURLOPT_CONNECTTIMEOUT
選項的值進行比較。 您還可以將total_time
與您用於CURLOPT_TIMEOUT
的值進行比較。 如果你轉出curl_getinfo($ch)
你會看到還有很多其他的計時器,你可以推斷出你需要的任何東西。 curl_error($ch)
返回的字符串。 如果擊中了任何*_TIMEOUT
選項,則會返回如下字符串: 操作在2001毫秒后超時,收到0字節
您可以使用以下功能嘗試連接3次,如果不成功則停止。 每次嘗試都會增加超時,以防服務器“滿”並且只需要一點時間。
public function functionName($attempt = 0) {
if ($attemp >= 3) {
return FALSE;
}
$TIMEOUT = 1;
$ch = curl_init();
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $TIMEOUT + $attempt);
curl_exec($ch);
if (!curl_errno($ch)) {
$info = curl_getinfo($ch);
if ($info['total_time'] > $TIMEOUT) {
$this->functionName($attempt++);
} else {
return TRUE;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.