PHP Query method for IP location
The implementation method is as follows:
The code is as follows:
/**
*@ Date 2010.12.21
Note: file header [offset of first index (4byte)] + [offset address of last index (4byte)] 8 bytes
Record area [end IP (4byte)] + [Region 1] + [Area 2] 4 bytes + indefinite length
Index area [Start IP (4byte)] + [offset address to record area (3byte)] 7 bytes
*/
Class iplocation{
var $fp;
var $firstip; Offset address of the first IP index
var $lastip; Offset address of the last IP index
var $totalip; Total IP number
/*
|----------------------------------------------------------------------------
| constructor, initialize some of the variables
|----------------------------------------------------------------------------
|
*/
function iplocation ($datfile = "Qqwry.dat") {
$this->fp=fopen ($datfile, ' RB ') or Die ("Qqwry.dat does not exist, please go online to download the pure IP database, ' Qqwry.dat ' put in the current directory"); Binary mode Open
$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 IP total index area is a fixed length of 7 bytes, which is divided by 7,
Register_shutdown_function (Array ($this, "CLOSEFP")); In order to be compatible with the following versions of PHP5, this class does not use destructors to automatically shut down IP libraries.
}
/*
|----------------------------------------------------------------------------
| Close IP Library
|----------------------------------------------------------------------------
|
*/
function Closefp () {
Fclose ($this->FP);
}
/*
|----------------------------------------------------------------------------
| Read 4 bytes and unzip to long mode
|----------------------------------------------------------------------------
|
*/
function get4b () {
$str =unpack ("V", Fread ($this->fp,4));
return $STR [1];
}
/*
|----------------------------------------------------------------------------
| Read redirected offset address
|----------------------------------------------------------------------------
|
*/
function GetOffset () {
$str =unpack ("V", Fread ($this->fp,3). chr (0));
return $STR [1];
}
/*
|----------------------------------------------------------------------------
| Read detailed address information for IP
|----------------------------------------------------------------------------
|
*/
function Getstr () {
$split =fread ($this->fp,1);
while (Ord ($split)!=0) {
$str. = $split;
$split =fread ($this->fp,1);
}
return $str;
}
/*
|----------------------------------------------------------------------------
| Convert IP to IPv4 Internet address via ip2long, then compress it into Big-endian byte order to compare with IP address in 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;
}
/*
|----------------------------------------------------------------------------
| Gets the flag 1 or 2 to determine whether the address is redirected
|----------------------------------------------------------------------------
|
*/
function Getflag () {
Return fread ($this->fp,1);
}
/*
|----------------------------------------------------------------------------
| Searching for IP in the index area using the binary lookup method
|----------------------------------------------------------------------------
|
*/
function Searchip ($IP) {
$ip =gethostbyname ($IP); Turn a domain name into an IP
$ip _offset["IP"]= $ip;
$ip = $this->iptoint ($IP); Convert IP to Growth integer
$firstip = 0; Top boundary of search
$lastip = $this->totalip; The bottom boundary of the search
$ipoffset = $this->lastip; The offset address initialized to the last IP address
while ($firstip <= $lastip) {
$i =floor (($firstip + $lastip)/2); Calculate approximate intermediate records the floor function calculates the largest integer of a given floating-point number, which is the four-five-loft
Fseek ($this->fp, $this->firstip + $i * 7); Positioning pointers to intermediate records
$startip =strrev (fread ($this->fp,4)); Reads the start IP address in the current index area and converts 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); Gets the absolute address of the IP within the index area
$ipoffset = $ip _offset["offset"];
$address ["IP"]= $ip _offset["IP"];
Fseek ($this->fp, $ipoffset); Navigate to Index Area
$address ["StartIP"]=long2ip ($this->get4b ()); Start IP address in index area
$address _offset= $this->getoffset (); Gets the offset address of the IP within the index area within the IP record area
Fseek ($this->fp, $address _offset); Locate within the record area
$address ["EndIP"]=long2ip ($this->get4b ()); End IP address in the record area
$flag = $this->getflag (); Read Flag byte
Switch (ord ($flag)) {
Case 1://Region 1 Area 2 redirect
$address _offset= $this->getoffset (); Read REDIRECT Address
Fseek ($this->fp, $address _offset); Position the pointer to the redirected address
$flag = $this->getflag (); Read Flag byte
Switch (ord ($flag)) {
Case 2://Region 1 redirect again,
Fseek ($this->fp, $this->getoffset ());
$address ["area1"]= $this->getstr ();
Fseek ($this->fp, $address _offset+4); Jump 4 bytes
$address ["Area2"]= $this->readaddress (); Region 2 There may be redirects, there may not be
Break
Default://Region 1, Region 2 None redirected
Fseek ($this->fp, $address _offset); Position the pointer to the redirected address
$address ["area1"]= $this->getstr ();
$address ["Area2"]= $this->readaddress ();
Break
}
Break
Case 2://Region 1 REDIRECT Region 2 No redirect
$address 1_offset= $this->getoffset (); Read REDIRECT Address
Fseek ($this->fp, $address 1_offset);
$address ["area1"]= $this->getstr ();
Fseek ($this->fp, $address _offset+8);
$address ["Area2"]= $this->readaddress ();
Break
Default://Region 1 area 2 no redirects
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;
}
}
/* Use 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. HTML www.bkjia.com true http://www.bkjia.com/phpjc/922886.html techarticle php the method of querying IP location is as follows: The code is as follows:? PHP/** *@ Date 2010.12.21 Note: file header [offset of first index (4byte)] + [offset of last index ...