get_file_contents连接太多

时间:2016-02-28 03:10:36

标签: php arrays

我在使用此代码时遇到问题。它应该得到访问者的国家代码。

$ipot = $_SERVER['REMOTE_ADDR'];
$details = json_decode(file_get_contents("http://ipinfo.io/{$ipot}"));

echo 'Your country region code is '.$details->country.'';

我收到此错误:

  

警告:file_get_contents(http://ipinfo.io/173.245.48.118):无法打开流:HTTP请求失败!

中的HTTP / 1.1 429请求过多

1 个答案:

答案 0 :(得分:0)

看起来您的服务器因为向ipinfo.io提出太多/频繁请求而被禁止

..我可以建议另一种方法吗? 从http://software77.net/geo-ip/下载Ipv4ToCountry.csv文件(或者从https://raw.githubusercontent.com/divinity76/http_log_parser/master/Ipv4ToCountry.csv下载过时的版本),

并使用此代码获取国家/地区?需要pdo sqlite3;

function ipv4_to_country_v2($ipv4){
    static $ip=false;
    $ipv4=filter_var($ipv4,FILTER_VALIDATE_IP,array('flags'=>FILTER_FLAG_IPV4,'options'=>array('default'=>false)));
    if($ipv4===false){
        throw new InvalidArgumentException('input is NOT a valid ipv4 address.. (sorry, no ipv6 support yet.)');
    }
    //$ip=ip2long($ipv4);
    $ip=ipv4touint($ipv4);
    if($ip===false){
        throw new UnexpectedValueException('input passed FILTER_FLAG_IPV4, but ip2long could not convert it! should never happen...');
    }
    static $ipdb=false;
    static $stm=false;
    if($ipdb===false){
        $ipdb=call_user_func(function(){
            $ipdb=new PDO('sqlite::memory:','','',array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
            $ipdb->query('CREATE TABLE `ipranges` (`iprange_start` INTEGER UNIQUE,`iprange_end` INTEGER UNIQUE,`country` VARCHAR(255));');
            assert(is_readable('Ipv4ToCountry.csv'));
            $iplist_raw=file_get_contents('Ipv4ToCountry.csv');
            $matches=array();
            $rex_ret=preg_match_all('/\\"([^\\"]*)\\"\\,\\"([^\\"]*)\\"\\,\\"([^\\"]*)\\"\\,\\"([^\\"]*)\\"\\,\\"([^\\"]*)\\"\\,\\"([^\\"]*)\\"\\,\\"([^\\"]*)\\"/',$iplist_raw,$matches);
            assert($rex_ret>9001);
            unset($matches[0],$iplist_raw);
            $iplist=array();
            //var_dump($rex_ret,$matches);
            $ipdb->beginTransaction();
            $stm=$ipdb->prepare('INSERT OR IGNORE INTO `ipranges` (`iprange_start`,`iprange_end`,`country`) VALUES(:iprange_start,:iprange_end,:country);');
            $stm->bindParam(':iprange_start', $ins_iprange_start, PDO::PARAM_INT);
            $stm->bindParam(':iprange_end', $ins_iprange_end, PDO::PARAM_INT);
            $stm->bindParam(':country', $ins_country, PDO::PARAM_STR);
            for($i=0;$i<$rex_ret;++$i){
                //$tmparr=array();
                # IP FROM      IP TO        REGISTRY  ASSIGNED   CTRY CNTRY COUNTRY
                # "1346797568","1346801663","ripencc","20010601","il","isr","Israel"
                //$tmparr['HHB_IPRANGE_START']=(int)$matches[1][$i];
                //$tmparr['HHB_IPRANGE_END']=(int)$matches[2][$i];
                //$tmparr['registry']=$matches[3][$i];
                //$tmparr['assigned']=$matches[4][$i];
                //$tmparr['ctry']=$matches[5][$i];
                //$tmparr['cntry']=$matches[6][$i];
                //$tmparr['HHB_COUNTRY']=$matches[7][$i];
                //$iplist[]=$tmparr;
                $ins_iprange_start=$matches[1][$i];
                $ins_iprange_end=$matches[2][$i];
                $ins_country=$matches[7][$i];
                //var_dump('adding: ',$ins_iprange_start,$ins_iprange_end,$ins_country);
                $stm->execute();
            }
            $ipdb->commit();
            return $ipdb;
        });
        $stm=$ipdb->prepare('SELECT `country` FROM `ipranges` WHERE :ip >= `iprange_start` AND :ip <= `iprange_end` LIMIT 1');
        //$stm->bindParam(':ip',$ip,PDO::PARAM_INT);
        $stm->bindParam(':ip',$ip,PDO::PARAM_STR);
    }
    $stm->execute();
    if(false!==($row=$stm->fetch(PDO::FETCH_ASSOC))){
        return $row['country'];
    }
    return 'unknown_country';
}
function ipv4touint($ipv4){
    return sprintf('%u',ip2long($ipv4));
}

如果代码运行速度太慢,请保存数据库,而不是每次重启php时都在内存中重新创建(上面的代码是为一个项目编写的,其中ipv4_to_country_v2将被称为数十万或数百万次,每个运行和静态创建数据库并没有太大的区别)

编辑:添加了ipv4touint