dongyanju0945 2016-02-28 03:10
浏览 88

get_file_contents连接太多

I'm having trouble with this code. It is supposed to get the country code of the visitor.

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

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

and I get this error:

Warning: file_get_contents(http://ipinfo.io/173.245.48.118): failed to open stream: HTTP request failed! HTTP/1.1 429 Too Many Requests in

  • 写回答

1条回答 默认 最新

  • doubai9014 2016-02-28 03:32
    关注

    looks like your server is getting banned for making too many/frequent requests to ipinfo.io

    .. may i suggest an alternative approach? download the Ipv4ToCountry.csv file from http://software77.net/geo-ip/ (or alternatively an outdated version from https://raw.githubusercontent.com/divinity76/http_log_parser/master/Ipv4ToCountry.csv ) ,

    and get the country with this code? requires 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));
    }
    

    and if the code runs too slow for you, save the database instead of recreating it in-memory every php restart (the code above were written for a project where ipv4_to_country_v2 would be called hundreds of thousands, or millions of times, per run and the static creation of the database didn't really make much of a difference)

    edit: added ipv4touint

    评论

报告相同问题?

悬赏问题

  • ¥15 基于双目测规则物体尺寸
  • ¥15 wegame打不开英雄联盟
  • ¥15 公司的电脑,win10系统自带远程协助,访问家里个人电脑,提示出现内部错误,各种常规的设置都已经尝试,感觉公司对此功能进行了限制(我们是集团公司)
  • ¥15 救!ENVI5.6深度学习初始化模型报错怎么办?
  • ¥30 eclipse开启服务后,网页无法打开
  • ¥30 雷达辐射源信号参考模型
  • ¥15 html+css+js如何实现这样子的效果?
  • ¥15 STM32单片机自主设计
  • ¥15 如何在node.js中或者java中给wav格式的音频编码成sil格式呢
  • ¥15 不小心不正规的开发公司导致不给我们y码,