PHP获取IP地址所在地信息的实例(使用纯真IP数据库qqwry.dat)
如下所示:
<?php $data='254.254.254.254'; echoip2long($data); functiongetIP() { if(getenv("HTTP_CLIENT_IP")&&strcasecmp(getenv("HTTP_CLIENT_IP"),"unknown")) $ip=getenv("HTTP_CLIENT_IP"); elseif(getenv("HTTP_X_FORWARDED_FOR")&&strcasecmp(getenv("HTTP_X_FORWARDED_FOR"),"unknown")) $ip=getenv("HTTP_X_FORWARDED_FOR"); elseif(getenv("REMOTE_ADDR")&&strcasecmp(getenv("REMOTE_ADDR"),"unknown")) $ip=getenv("REMOTE_ADDR"); elseif(isset($_SERVER['REMOTE_ADDR'])&&$_SERVER['REMOTE_ADDR']&&strcasecmp($_SERVER['REMOTE_ADDR'],"unknown")) $ip=$_SERVER['REMOTE_ADDR']; else $ip="0.0.0.0"; return$ip; } classIpLocation{ //数据文件指针 var$fp; var$firstip; var$lastip; var$totalip; functiongetlong(){ //unpack从二进制字符串对数据进行解包 //将读取的little-endian编码的4个字节转化为长整型数,fread安全读取二进制文件 $result=unpack('Vlong',fread($this->fp,4)); return$result['long']; } functiongetlong3(){ //将读取的little-endian编码的3个字节转化为长整型数 $result=unpack('Vlong',fread($this->fp,3).chr(0)); return$result['long']; } functionpackip($ip){ //pack把数据装入一个二进制字符串 //ip2long将IP地址转成无符号的长整型,也可以用来验证IP地址 returnpack('N',intval(ip2long($ip))); } functiongetstring($data=""){ $char=fread($this->fp,1); while(ord($char)>0){//ord返回字符的ASCII值,字符串按照C格式保存,以\0结束 $data.=$char; $char=fread($this->fp,1); } return$data; } functiongetarea(){ $byte=fread($this->fp,1);//标志字节 switch(ord($byte)){ case0://没有区域信息 $area=""; break; case1: case2://标志字节为1或2,表示区域信息被重定向 fseek($this->fp,$this->getlong3()); $area=$this->getstring(); break; default://否则,表示区域信息没有被重定向 $area=$this->getstring($byte); break; } return$area; } functiongetlocation($ip){ if(!$this->fp)returnnull;//如果数据文件没有被正确打开,则直接返回空 $location['ip']=gethostbyname($ip);//域名转化为IP地址 $ip=$this->packip($location['ip']);//将输入的IP地址转化为可比较的IP地址 //不合法的IP地址会被转化为255 //对分搜索 $l=0;//搜索的下边界 $u=$this->totalip;//搜索的上边界 $findip=$this->lastip;//如果没有找到就返回最后一条IP记录(QQWry.Dat的版本信息) while($l<=$u){//当上边界小于下边界时,查找失败 $i=floor(($l+$u)/2);//计算近似中间记录 fseek($this->fp,$this->firstip+$i*7); $beginip=strrev(fread($this->fp,4));//获取中间记录的开始IP地址,strrev反转字符串 //strrev函数在这里的作用是将little-endian的压缩IP地址转化为big-endian的格式,便于比较 //关于little-endian与big-endian参考:http://baike.baidu.com/view/2368412.htm if($ip<$beginip){//用户的IP小于中间记录的开始IP地址时 $u=$i-1;//将搜索的上边界修改为中间记录减一 } else{ fseek($this->fp,$this->getlong3()); $endip=strrev(fread($this->fp,4));//获取中间记录的结束IP地址 if($ip>$endip){//用户的IP大于中间记录的结束IP地址时 $l=$i+1;//将搜索的下边界修改为中间记录加一 } else{//用户的IP在中间记录的IP范围内时 $findip=$this->firstip+$i*7; break;//则表示找到结果,退出循环 } } } fseek($this->fp,$findip); $location['beginip']=long2ip($this->getlong());//用户IP所在范围的开始地址 $offset=$this->getlong3(); fseek($this->fp,$offset); $location['endip']=long2ip($this->getlong());//用户IP所在范围的结束地址 $byte=fread($this->fp,1);//标志字节 switch(ord($byte)){ case1://标志字节为1,表示国家和区域信息都被同时重定向 $countryOffset=$this->getlong3();//重定向地址 fseek($this->fp,$countryOffset); $byte=fread($this->fp,1);//标志字节 switch(ord($byte)){ case2://标志字节为2,表示国家信息又被重定向 fseek($this->fp,$this->getlong3()); $location['country']=$this->getstring(); fseek($this->fp,$countryOffset+4); $location['area']=$this->getarea(); break; default://否则,表示国家信息没有被重定向 $location['country']=$this->getstring($byte); $location['area']=$this->getarea(); break; } break; case2://标志字节为2,表示国家信息被重定向 fseek($this->fp,$this->getlong3()); $location['country']=$this->getstring(); fseek($this->fp,$offset+8); $location['area']=$this->getarea(); break; default://否则,表示国家信息没有被重定向 $location['country']=$this->getstring($byte); $location['area']=$this->getarea(); break; } if($location['country']=="CZNET"){//CZNET表示没有有效信息 $location['country']="未知"; } if($location['area']=="CZNET"){ $location['area']=""; } return$location; } /** *构造函数,打开QQWry.Dat文件并初始化类中的信息 */ functionIpLocation($filename="qqwry.dat"){ $this->fp=0; if(($this->fp=@fopen($filename,'rb'))!==false){ $this->firstip=$this->getlong(); $this->lastip=$this->getlong(); $this->totalip=($this->lastip-$this->firstip)/7; //注册析构函数,使其在程序执行结束时执行 register_shutdown_function(array(&$this,'_IpLocation')); } } /** *析构函数,用于在页面执行结束后自动关闭打开的文件 */ function_IpLocation(){ if($this->fp){ fclose($this->fp); } $this->fp=0; } } header("content-Type:text/html;charset=gbk"); $ipOrDomain='110.0.0.0'; //$ipOrDomain='www.baidu.com'; $iplocation=newIpLocation(); $location=$iplocation->getlocation($ipOrDomain); $address=mb_convert_encoding($location['country'].$location['area'],"gbk","gbk"); echo$address; ?>
以上这篇PHP获取IP地址所在地信息的实例(使用纯真IP数据库qqwry.dat)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。