[英]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.