Parse PHP based on IP query location (very useful, net used) _php tips

Source: Internet
Author: User
Tags fread integer numbers ord unpack
DAT files, information files about IP-corresponding areas
Qqwry.dat file
Download yourself Online

class file, parsing the Qqwry.data file's
iplocation.php File
Copy Code code as follows:

<?php
Class Iplocation {
/**
* @var Resource pointer
*/
Private $fp;
/**
* Offset address of the first IP record
* @var int
*/
Private $firstip;
/**
* Offset address of the last IP record
* @var int
*/
Private $lastip;
/**
* Total number of IP records (does not contain version information records)
* @var int
*/
Private $totalip;
/**
* constructor, open the QQWry.Dat file and initialize the information in the class
* @param string $filename
* @return Iplocation
*/
Public function __construct ($filename = "Qqwry.dat") {
$this-&GT;FP = 0;
if ($this-&GT;FP = @fopen ($filename, ' RB ')!== false) {
$this->firstip = $this->getlong ();
$this->lastip = $this->getlong ();
$this->totalip = ($this->lastip-$this->firstip)/7;
}
}
/**
* Returns the long integer read
* @access Private
* @return int
*/
Public Function Getlong () {
Converts 4 bytes of read Little-endian encoded into long integer numbers
$result = Unpack (' Vlong ', fread ($this-&GT;FP, 4));
return $result [' Long '];
}
/**
* Returns the 3-byte long integer read
*
* @access Private
* @return int
*/
Public Function Getlong3 () {
Converts 3 bytes of read Little-endian encoded into long integer numbers
$result = Unpack (' Vlong ', fread ($this-&GT;FP, 3). chr (0));
return $result [' Long '];
}
/**
* Returns the compressed IP address that can be compared after compression
*
* @access Private
* @param string $ip
* @return String
*/
Public Function Packip ($IP) {
Converts an IP address to a long integer and returns false if the IP address is incorrect in PHP5.
Then intval converts flase to an integer-1, which is then compressed into a Big-endian encoded string
Return pack (' N ', Intval (Ip2long ($IP));
}
/**
* Returns the Read string
*
* @access Private
* @param string $data
* @return String
*/
Public Function GetString ($data = "") {
$char = Fread ($this->fp, 1);
while (Ord ($char) > 0) {//string is saved in C format, ending with a
$data. = $char; After fonts the read Word to the given string
$char = Fread ($this->fp, 1);
}
Return mb_convert_encoding ($data, ' utf-8 ', ' gb2312 ');
}
/**
* Return to regional information
*
* @access Private
* @return String
*/
Public Function Getarea () {
$byte = Fread ($this->fp, 1); Flag byte
Switch (ord ($byte)) {
Case 0://No regional information
$area = "";
Break
Case 1:
Case 2://The flag byte is 1 or 2, indicating that the zone information is redirected
Fseek ($this->fp, $this->getlong3 ());
$area = $this->getstring ();
Break
Default://Otherwise, indicates that zone information is not redirected
$area = $this->getstring ($byte);
Break
}
return $area;
}
/**
* Return the area information according to the given IP address or domain name
* @access Public
* @param string $ip
* @return Array
*/
function GetLocation ($IP) {
if (! $this-&GT;FP) return null; If the data file is not opened correctly, return null directly
$location [' ip '] = gethostbyname ($IP); Converts the domain name entered into an IP address
$ip = $this->packip ($location [' IP ']); Converts the IP address entered into a comparable IP address
An illegal IP address is converted to 255.255.255.255.
Pair-Search
$l = 0; Search the bottom boundary
$u = $this->totalip; Top bounds for Search
$findip = $this->lastip; Returns the last IP record (QQWry.Dat version information) if it is not found
while ($l <= $u) {//When the top boundary is less than the bottom boundary, the lookup fails
$i = Floor (($l + $u)/2); Calculating approximate intermediate records
Fseek ($this->fp, $this->firstip + $i * 7);
$beginip = Strrev (fread ($this-&GT;FP, 4)); Get start IP address of intermediate record
The Strrev function here is to convert Little-endian's compressed IP address to Big-endian format
For comparison purposes, followed by the same.
if ($ip < $beginip) {//The user's IP is less than the start IP address of the intermediate record
$u = $i-1; Modifies the top boundary of the search to intermediate records minus one
}else{
Fseek ($this->fp, $this->getlong3 ());
$endip = Strrev (fread ($this-&GT;FP, 4)); Get the end IP address of an intermediate record
if ($ip > $endip) {//user's IP is greater than the end IP address of the intermediate record
$l = $i + 1; Modify the bottom boundary of the search to an intermediate record plus a
}else{//user's IP is within the IP range of the intermediate record
$findip = $this->firstip + $i * 7;
Break Indicates that the result is found and the loop is exited
}
}
}
Get the IP geographic information found
Fseek ($this->fp, $findip);
$location [' beginip '] = Long2ip ($this->getlong ()); Start address of the range where the user IP resides
$offset = $this->getlong3 ();
Fseek ($this->fp, $offset);
$location [' endip '] = Long2ip ($this->getlong ()); End address of User IP range
$byte = Fread ($this->fp, 1); Flag byte
Switch (ord ($byte)) {
Case 1://The flag byte is 1, indicating that both national and regional information is redirected simultaneously
$countryOffset = $this->getlong3 (); REDIRECT Address
Fseek ($this->fp, $countryOffset);
$byte = Fread ($this->fp, 1); Flag byte
Switch (ord ($byte)) {
Case 2://Sign Byte 2, indicating that country information is redirected
Fseek ($this->fp, $this->getlong3 ());
$location [' country '] = $this->getstring ();
Fseek ($this->fp, $countryOffset + 4);
$location [' area '] = $this->getarea ();
Break
Default://Otherwise, indicates that the country information has not been redirected
$location [' country '] = $this->getstring ($byte);
$location [' area '] = $this->getarea ();
Break
}
Break
Case 2://Flag Byte is 2, indicating that national information is redirected
Fseek ($this->fp, $this->getlong3 ());
$location [' country '] = $this->getstring ();
Fseek ($this->fp, $offset + 8);
$location [' area '] = $this->getarea ();
Break
Default://Otherwise, indicates that the country information has not been redirected
$location [' country '] = $this->getstring ($byte);
$location [' area '] = $this->getarea ();
Break
}
if ($location [' country '] = = "Cz88.net") {//CZ88. NET indicates no valid information
$location [' country '] = "Unknown";
}
if ($location [' area '] = = "Cz88.net") {
$location [' area '] = ' ";
}
return $location;
}

/**
* destructor, used to automatically close open files after the end of a page execution.
*
*/
function __desctruct () {
if ($this->fp) {
Fclose ($this-&GT;FP);
}
$this-&GT;FP = 0;
}
}
?>

This also can download online, also can copy here, here is also very full.
Execute file, I'm here called ip_location.php file
Copy Code code as follows:

<?php
function Getipplace () {
Require_once ("iplocation.php")/Load class file iplocation.php
$ipfile = "Qqwry.dat"; Obtain an information file for an IP-corresponding region
$iplocation = new Iplocation ($ipfile); New Iplocation ($ipfile) $ipfile IP counterpart region information file
$ipresult = $iplocation->getlocation ("IP Address"); Get regional getlocation ("IP Region") based on IP address
return $ipresult;
}
Print_r ($getIpPlace ()); Call method
?>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.