在PHP中,curl_exec
有多个选项可用于中止花费时间过长的请求CURLOPT_TIMEOUT
,CURLOPT_CONNECTTIMEOUT
,CURLOPT_LOW_SPEED_TIME
等。我相信所有这些情况的errno是28(这只表示操作超时),libcurl是否根据达到的超时报告任何不同的内容,并且PHP是否公开了这个功能?
我尝试在简单的PHP函数上更改这些选项的值,但是无法生成非28错误。
function curl_test() {
$ch = curl_init();
$options = array(
CURLOPT_URL => 'http://www.google.com',
CURLOPT_HEADER => false,
CURLOPT_TIMEOUT_MS => 1000,
CURLOPT_CONNECTTIMEOUT_MS => 10,
);
curl_setopt_array($ch, $options);
curl_exec($ch);
$out = curl_errno($ch);
curl_close($ch);
return $out;
}
答案 0 :(得分:1)
为了实现这一目标,我认为我们只需要测试我们正在寻找的Timeout。所以我看到以下场景:
我们可以使用其他方法检查第一次超时。所以我们这样做:
<?php
$site="http://www.google.com";
$content = file_get_contents($site);
if($content === false){
// Host dead, handle error here...
}
?>
参考:How can I handle the warning of file_get_contents() function in PHP?
此时,我们知道我们不应该获得连接超时。我们可以继续执行curl并知道它将是一个操作超时或速度。
<?php
function curl_run($opts){
$content = file_get_contents($opts[CURLOPT_URL]);
if($content === false){
return false;
} else {
$resp = array();
$time_start = microtime(true);
$ch = curl_init();
curl_setopt_array($ch, $opts);
$resp['result'] = curl_exec($ch);
$time_end = microtime(true);
$resp['info'] = curl_getinfo($ch);
if(curl_errno($ch)){
$resp['error'] = curl_error($ch);
}
curl_close($ch);
$resp['time'] = $time_end - $time_start; // Time it took
return $resp;
}
}
$url = isset($_GET['url'])?$_GET['url']:"http://www.google.com/";
$options = array(
CURLOPT_URL => $url,
CURLOPT_HEADER => true,
CURLOPT_TIMEOUT_MS => 1000,
CURLOPT_CONNECTTIMEOUT_MS => 10,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_VERBOSE => 1
);
$results = curl_run($options);
if($results){
echo "<h2>Options</h2>\r\n";
echo "<pre>";
foreach($options as $k => $v){
echo "$k: $v\r\n";
}
echo "</pre>";
echo "<h2>Info</h2>\r\n";
echo "<pre>";
foreach($results['info'] as $k => $v){
echo "$k: $v\r\n";
}
echo "time: {$results['time']}\r\n";
echo "</pre>\r\n";
if(isset($results['error'])){
echo "<h2>Error</h2>\r\n";
echo "<pre>{$results['error']}</pre>\r\n";
}
echo "<h2>Response</h2>\r\n";
echo "<pre>" . htmlentities($results['result']) . "</pre>";
}
?>
我们应该能够查看所有这些并确定执行操作所花费的时间是否接近我们的超时设置之一。否则我们也会在info
下拥有大量数据。如果返回false,我们知道主机无法访问。
进行了进一步测试,您可以在此处查看:http://www.yrmailfrom.me/projects/php/curl_test1.php?url=http://www.apple.com/
我发现Apple.com花了14毫秒,所以它成了一个很好的测试。
示例输出:
Options
10002: http://www.apple.com/
42: 1
155: 1000
156: 10
19913: 1
41: 1
Info
url: http://www.apple.com/
content_type:
http_code: 0
header_size: 0
request_size: 0
filetime: -1
ssl_verify_result: 0
redirect_count: 0
total_time: 0.014634
namelookup_time: 0.004297
connect_time: 0
pretransfer_time: 0
size_upload: 0
size_download: 0
speed_download: 0
speed_upload: 0
download_content_length: -1
upload_content_length: -1
starttransfer_time: 0
redirect_time: 0
redirect_url:
primary_ip:
certinfo: Array
primary_port: 0
local_ip:
local_port: 0
time: 0.014760017395
Error
Connection timed out after 14 milliseconds
Response