PHP判断IP并转跳到相应城市分站的方法
本文实例讲述了PHP判断IP并转跳到相应城市分站的方法。分享给大家供大家参考。具体实现方法如下:
<?php
classQQWry{
var$StartIP=0;
var$EndIP=0;
var$Country='';
var$Local='';
var$CountryFlag=0;
//标识Country位置
//0x01,随后3字节为Country偏移,没有Local
//0x02,随后3字节为Country偏移,接着是Local
//其他,Country,Local,Local有类似的压缩。可能多重引用。
var$fp;
var$FirstStartIp=0;
var$LastStartIp=0;
var$EndIpOff=0;
functiongetStartIp($RecNo){
$offset=$this->FirstStartIp+$RecNo*7;
@fseek($this->fp,$offset,SEEK_SET);
$buf=fread($this->fp,7);
$this->EndIpOff=ord($buf[4])+(ord($buf[5])*256)+(ord($buf[6])*256*256);
$this->StartIp=ord($buf[0])+(ord($buf[1])*256)+(ord($buf[2])*256*256)+(ord($buf[3])*256*256*256);
return$this->StartIp;
}
functiongetEndIp(){
@fseek($this->fp,$this->EndIpOff,SEEK_SET);
$buf=fread($this->fp,5);
$this->EndIp=ord($buf[0])+(ord($buf[1])*256)+(ord($buf[2])*256*256)+(ord($buf[3])*256*256*256);
$this->CountryFlag=ord($buf[4]);
return$this->EndIp;
}
functiongetCountry(){
switch($this->CountryFlag){
case1:
case2:
$this->Country=$this->getFlagStr($this->EndIpOff+4);
//echosprintf('EndIpOffset=(%x)',$this->EndIpOff);
$this->Local=(1==$this->CountryFlag)?'':$this->getFlagStr($this->EndIpOff+8);
break;
default:
$this->Country=$this->getFlagStr($this->EndIpOff+4);
$this->Local=$this->getFlagStr(ftell($this->fp));
}
}
functiongetFlagStr($offset){
$flag=0;
while(1){
@fseek($this->fp,$offset,SEEK_SET);
$flag=ord(fgetc($this->fp));
if($flag==1||$flag==2){
$buf=fread($this->fp,3);
if($flag==2){
$this->CountryFlag=2;
$this->EndIpOff=$offset-4;
}
$offset=ord($buf[0])+(ord($buf[1])*256)+(ord($buf[2])*256*256);
}
else{
break;
}
}
if($offset<12)
return'';
@fseek($this->fp,$offset,SEEK_SET);
return$this->getStr();
}
functiongetStr()
{
$str='';
while(1){
$c=fgetc($this->fp);
//echo"$cn";
if(ord($c[0])==0)
break;
$str.=$c;
}
//echo"$strn";
return$str;
}
functionqqwry($dotip=''){
if(!is_string($dotip)||$dotip==''){return;}
if(preg_match("/^127/",$dotip)){$this->Country="本地网络";return;}
elseif(preg_match("/^192/",$dotip)){$this->Country="局域网";return;}
$nRet;
$ip=$this->IpToInt($dotip);
$this->fp=fopen(__QQWRY__,"rb");
if($this->fp==NULL){
$szLocal="OpenFileError";
return1;
}
@fseek($this->fp,0,SEEK_SET);
$buf=fread($this->fp,8);
$this->FirstStartIp=ord($buf[0])+(ord($buf[1])*256)+(ord($buf[2])*256*256)+(ord($buf[3])*256*256*256);
$this->LastStartIp=ord($buf[4])+(ord($buf[5])*256)+(ord($buf[6])*256*256)+(ord($buf[7])*256*256*256);
$RecordCount=floor(($this->LastStartIp-$this->FirstStartIp)/7);
if($RecordCount<=1){
$this->Country="FileDataError";
fclose($this->fp);
return2;
}
$RangB=0;
$RangE=$RecordCount;
//Match...
while($RangB<$RangE-1)
{
$RecNo=floor(($RangB+$RangE)/2);
$this->getStartIp($RecNo);
if($ip==$this->StartIp)
{
$RangB=$RecNo;
break;
}
if($ip>$this->StartIp)
$RangB=$RecNo;
else
$RangE=$RecNo;
}
$this->getStartIp($RangB);
$this->getEndIp();
if(($this->StartIp<=$ip)&&($this->EndIp>=$ip)){
$nRet=0;
$this->getCountry();
//这样不太好..............所以..........
$this->Local=str_replace("areaerror","",$this->Local);
}
else{
$nRet=3;
$this->Country='未知';
$this->Local='';
}
fclose($this->fp);
$this->Country=preg_replace("/(CZ88.NET)|(纯真网络)/","局域网/未知",$this->Country);
$this->Local=preg_replace("/(CZ88.NET)|(纯真网络)/","局域网/未知",$this->Local);
//////////////看看$nRet在上面的值是什么0和3,于是将下面的行注释掉
return$nRet;
//return"$this->Country$this->Local";#如此直接返回位置和国家便可以了
}
functionIpToInt($Ip){
$array=explode('.',$Ip);
$Int=($array[0]*256*256*256)+($array[1]*256*256)+($array[2]*256)+$array[3];
return$Int;
}
}
?>
实例演示如下:
$QQWry=newQQWry;
$QQWry->QQWry("60.31.95.255");
$country=$QQWry->Country;
echo$QQWry->Country.",".$QQWry->Local;
希望本文所述对大家的php程序设计有所帮助。