我希望在检测到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
}
答案 0 :(得分:3)
要获取有关请求的信息,您可以查看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'];
}
在信息数组中,您可以收到以下数据:
答案 1 :(得分:3)
您有两个选择:
curl_getinfo($ch)
返回的数组中,将connect_time
与您用于CURLOPT_CONNECTTIMEOUT
选项的值进行比较。您还可以将total_time
与您用于CURLOPT_TIMEOUT
的值进行比较。如果你转出curl_getinfo($ch)
,你会看到还有很多其他的计时器,你可以推断出你需要的任何东西。curl_error($ch)
返回的字符串。如果您的任何*_TIMEOUT
选项被点击,则会返回如下字符串:操作在2001毫秒后收到0字节后超时
答案 2 :(得分:1)
您可以使用以下功能尝试连接3次,如果不成功则停止。每次尝试都会增加超时时间,以防万一服务器是&#34; FULL&#34;只需要一点时间。
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;
}
}
}