/**
*@ date 2010.12.21
Note: File header [Offset of the first index (4byte)] + [Offset address of the last index (4byte)] 8 bytes
Record area [End IP (4byte)] + [Region 1] + [Region 2]
Index area [Start IP (4BYTE)] + [Displacement address (3byte)] 7 bytes
*/
class iplocation{
var $fp;
var $firstip; //Offset address of the first ip index
var $lastip; //The offset address of the last IP index
var $totalip; //Total number of IPs
/*
|------------------------------------------------- --------------------------
| Constructor, initialize some variables
|------------------------------------------------- --------------------------
|
*/
function iplocation($datfile = "qqwry.dat"){
$this->fp=fopen($datfile,'rb')or die("qqwry.dat does not exist, please go online
Download Innocence IP database, 'qqwry.dat' and put it in the current directory"); //Open in binary mode
$this->firstip = $this->get4b(); //The absolute offset address of the first ip index
$this->lastip = $this->get4b(); //The absolute offset address of the last ip index
$this->totalip =($this->lastip - $this->firstip)/7; //The total number of ips. The index area is a fixed length of 7 bytes. It needs to be divided by 7 here.
register_shutdown_function(array($this,"closefp")); //In order to be compatible with versions below php5, this class does not use a destructor and automatically closes the ip library.
}
/*
|------------------------------------------------- --------------------------
| Close ip library
|------------------------------------------------- --------------------------
|
*/
function closefp(){
fclose($this->fp);
}
/*
|------------------------------------------------- --------------------------
| Read 4 bytes and decompress into long mode
|------------------------------------------------- --------------------------
|
*/
function get4b(){
$str=unpack("v",fread($this->fp,4));
return $str[1];
}
/*
|------------------------------------------------- --------------------------
| Read the redirected offset address
|------------------------------------------------- --------------------------
|
*/
function getoffset(){
$str=unpack("v",fread($this->fp,3).chr(0));
return $str[1];
}
/*
|------------------------------------------------- --------------------------
| Read detailed address information of IP
|------------------------------------------------- --------------------------
|
*/
function getstr(){
$split=fread($this->fp,1);
while (ord($split)!=0) {
$str .=$split;
$split=fread($this->fp,1);
}
return $str;
}
/*
|------------------------------------------------- --------------------------
| Convert the ip to an ipv4 Internet address through ip2long, and then compress it into big-endian byte order for comparison with the ip address in the index area
|------------------------------------------------- --------------------------
|
*/
function iptoint($ip){
return pack("n",intval(ip2long($ip)));
}
/*
|------------------------------------------------- --------------------------
| Get address information
|------------------------------------------------- --------------------------
|
*/
function readaddress(){
$now_offset=ftell($this->fp); //Get the current pointer address
$flag=$this->getflag();
switch (ord($flag)){
case 0:
$address="";
break;
case 1:
case 2:
fseek($this->fp,$this->getoffset());
$address=$this->getstr();
break;
default:
fseek($this->fp,$now_offset);
$address=$this->getstr();
break;
}
return $address;
}
/*
|------------------------------------------------- --------------------------
| Get flag 1 or 2 to determine whether the address has been redirected
|------------------------------------------------- --------------------------
|
*/
function getflag(){
return fread($this->fp,1);
}
/*
|------------------------------------------------- --------------------------
| Use binary search method to search ip in the index area
|------------------------------------------------- --------------------------
|
*/
function searchip($ip){
$ip=gethostbyname($ip); //Convert domain name to ip
$ip_offset["ip"]=$ip;
$ip=$this->iptoint($ip); //Convert ip to long integer
$firstip=0; //The upper boundary of the search
$lastip=$this->totalip; //Lower boundary of search
$ipoffset=$this->lastip; //Initialized to the offset address of the last ip address
while ($firstip <= $lastip){
$i=floor(($firstip + $lastip) / 2); //Calculate approximate intermediate records The floor function calculates the largest integer smaller than a given floating point number. To put it bluntly, it means rounding off
fseek($this->fp,$this->firstip + $i * 7); //Locate the pointer to the middle record
$startip=strrev(fread($this->fp,4)); //Read the starting ip address in the current index area and convert its little-endian byte order to big-endian byte order
if ($ip < $startip) {
$lastip=$i - 1;
}
else {
fseek($this->fp,$this->getoffset());
$endip=strrev(fread($this->fp,4));
if ($ip > $endip){
$firstip=$i + 1;
}
else {
$ip_offset["offset"]=$this->firstip + $i * 7;
break;
}
}
}
return $ip_offset;
}
/*
|------------------------------------------------- --------------------------
| Get ip address details
|------------------------------------------------- --------------------------
|
*/
function getaddress($ip){
$ip_offset=$this->searchip($ip); //Get the absolute offset address of ip in the index area
$ipoffset=$ip_offset["offset"];
$address["ip"]=$ip_offset["ip"];
fseek($this->fp,$ipoffset); //Locate the index area
$address["startip"]=long2ip($this->get4b()); //Start ip address in the index area
$address_offset=$this->getoffset(); //Get the offset address of the ip in the index area in the ip record area
fseek($this->fp,$address_offset); //Locate the record area
$address["endip"]=long2ip($this->get4b()); //The end IP address in the record area
$flag=$this->getflag(); //Read flag byte
switch (ord($flag)) {
case 1: //Region 1 and region 2 are redirected
$address_offset=$this->getoffset(); //Read the redirect address
fseek($this->fp,$address_offset); //Locate the pointer to the redirected address
$flag=$this->getflag(); //Read flag byte
switch (ord($flag)) {
case 2: //Region 1 redirects again,
fseek($this->fp,$this->getoffset());
$address["area1"]=$this->getstr();
fseek($this->fp,$address_offset+4); //Jump 4 bytes
$address["area2"]=$this->readaddress(); //Area 2 may be redirected, but may not be redirected
break;
default: //Region 1 and region 2 have no redirection
fseek($this->fp,$address_offset); //Locate the pointer to the redirected address
$address["area1"]=$this->getstr();
$address["area2"]=$this->readaddress();
break;
}
break;
case 2: //Region 1 redirects Region 2 without redirection
$address1_offset=$this->getoffset(); //Read the redirect address
fseek($this->fp,$address1_offset);
$address["area1"]=$this->getstr();
fseek($this->fp,$address_offset+8);
$address["area2"]=$this->readaddress();
break;
default: //There is no redirection in region 1 and region 2
fseek($this->fp,$address_offset+4);
$address["area1"]=$this->getstr();
$address["area2"]=$this->readaddress();
break;
}
//*Filter some useless data
if (strpos($address["area1"],"cz88.net")!=false){
$address["area1"]="Unknown";
}
if (strpos($address["area2"],"cz88.net")!=false){
$address["area2"]=" ";
}
return $address;
}
}
/*Usage is as follows:*/
$ip=new iplocation("qqwry.dat");
$address=$ip->getaddress("61.129.51.27");
//$address=$ip->getaddress(www.jb51.net);
echo '
';
print_r($address);
?>
http://www.bkjia.com/PHPjc/922886.htmlwww.bkjia.comtruehttp: //www.bkjia.com/PHPjc/922886.htmlTechArticleThe specific implementation method of querying the IP location in php is as follows: The code is as follows: ?php /** *@ date 2010.12. 21 Note: File header [offset of the first index (4byte)] + [offset of the last index...