Parse php to query the region based on the ip address (very useful, available on the market)

Source: Internet
Author: User
Tags unpack

Dat file, information file about the ip corresponding region
Qqwry. dat file
Download it online by yourself

Class file, parse the qqwry. data File
IpLocation. php file
Copy codeThe Code is 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 (excluding version Records)
* @ Var int
*/
Private $ totalip;
/**
* Constructor: Open the QQWry. Dat file and initialize information in the class.
* @ Param string $ filename
* @ Return IpLocation
*/
Public function _ construct ($ 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;
}
}
/**
* Returns the number of long integers read.
* @ Access private
* @ Return int
*/
Public function getlong (){
// Convert the 4 bytes of the read little-endian encoding to the long integer
$ Result = unpack ('vlong', fread ($ this-> fp, 4 ));
Return $ result ['long'];
}
/**
* Returns the number of long integers read in three bytes.
*
* @ Access private
* @ Return int
*/
Public function getlong3 (){
// Convert the three bytes of the read little-endian encoding into a long integer.
$ Result = unpack ('vlong', fread ($ this-> fp, 3). chr (0 ));
Return $ result ['long'];
}
/**
* Return the IP addresses that can be compared after compression.
*
* @ Access private
* @ Param string $ ip
* @ Return string
*/
Public function packip ($ ip ){
// Convert the IP address to a long integer. If the IP address is incorrect in PHP5, False is returned,
// At this time, intval converts Flase to an integer-1, and then compresses it into a string encoded by big-endian.
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 and ended with \ 0
$ Data. = $ char; // after connecting the read characters to the given string
$ Char = fread ($ this-> fp, 1 );
}
Return mb_convert_encoding ($ data, 'utf-8', 'gb2312 ');
}
/**
* Returned region information
*
* @ Access private
* @ Return string
*/
Public function getarea (){
$ Byte = fread ($ this-> fp, 1); // flag byte
Switch (ord ($ byte )){
Case 0: // No region information
$ Area = "";
Break;
Case 1:
Case 2: // indicates that the region information is redirected when the byte is 1 or 2.
Fseek ($ this-> fp, $ this-> getlong3 ());
$ Area = $ this-> getstring ();
Break;
Default: // otherwise, the region information is not redirected.
$ Area = $ this-> getstring ($ byte );
Break;
}
Return $ area;
}
/**
* Return region information based on the given IP address or domain name
* @ Access public
* @ Param string $ ip
* @ Return array
*/
Function getlocation ($ ip ){
If (! $ This-> fp) return null; // if the data file is not properly opened, null is returned directly.
$ Location ['IP'] = gethostbyname ($ ip); // convert the entered domain name to an ip address
$ Ip = $ this-> packip ($ location ['IP']); // convert the input ip address to a comparable ip address.
// Invalid IP address will be converted to 255.255.255.255
// Split search
$ L = 0; // bottom boundary of the search
$ U = $ this-> totalip; // the upper boundary of the search
$ Findip = $ this-> lastip; // if not found, the last IP record is returned (QQWry. Dat version information)
While ($ l <= $ u) {// when the boundary is smaller than the bottom boundary, the search fails.
$ I = floor ($ l + $ u)/2); // calculate the approximate intermediate record
Fseek ($ this-> fp, $ this-> firstip + $ I * 7 );
$ Beginip = strrev (fread ($ this-> fp, 4); // obtain the starting IP address of the intermediate record
// The strrev function is used to convert the compressed IP address of little-endian to the big-endian format.
// Used for comparison.
If ($ ip <$ beginip) {// when the user's IP address is smaller than the starting ip address of the intermediate record
$ U = $ I-1; // change the upper boundary of the search to minus one for the intermediate record
} Else {
Fseek ($ this-> fp, $ this-> getlong3 ());
$ Endip = strrev (fread ($ this-> fp, 4); // obtain the end IP address of the intermediate record
If ($ ip> $ endip) {// when the user's IP address is greater than the end ip address of the intermediate record
$ L = $ I + 1; // change the bottom boundary of the search to an intermediate record plus one
} Else {// when the user's IP address is within the IP address range recorded in the middle
$ Findip = $ this-> firstip + $ I * 7;
Break; // indicates that the result is found and the loop is exited.
}
}
}
// Obtain the IP address location information.
Fseek ($ this-> fp, $ findip );
$ Location ['ininip'] = long2ip ($ this-> getlong (); // start address of the user's IP address range
$ Offset = $ this-> getlong3 ();
Fseek ($ this-> fp, $ offset );
$ Location ['enabled'] = long2ip ($ this-> getlong (); // end address of the user's IP address range
$ Byte = fread ($ this-> fp, 1); // flag byte
Switch (ord ($ byte )){
Case 1: // The flag byte is 1, indicating that both the country and region information are redirected at the same time.
$ CountryOffset = $ this-> getlong3 (); // redirect address
Fseek ($ this-> fp, $ countryOffset );
$ Byte = fread ($ this-> fp, 1); // flag byte
Switch (ord ($ byte )){
Case 2: // The flag byte is 2, indicating that the country information is redirected.
Fseek ($ this-> fp, $ this-> getlong3 ());
$ Location ['country'] = $ this-> getstring ();
Fseek ($ this-> fp, $ countryOffset + 4 );
$ Location ['region'] = $ this-> getarea ();
Break;
Default: // otherwise, the country information is not redirected.
$ Location ['country'] = $ this-> getstring ($ byte );
$ Location ['region'] = $ this-> getarea ();
Break;
}
Break;
Case 2: // The flag byte is 2, indicating that the country information is redirected.
Fseek ($ this-> fp, $ this-> getlong3 ());
$ Location ['country'] = $ this-> getstring ();
Fseek ($ this-> fp, $ offset + 8 );
$ Location ['region'] = $ this-> getarea ();
Break;
Default: // otherwise, the country information is not redirected.
$ Location ['country'] = $ this-> getstring ($ byte );
$ Location ['region'] = $ this-> getarea ();
Break;
}
If ($ location ['country'] = "CZ88.NET") {// CZ88.NET indicates no valid information
$ Location ['country'] = "unknown ";
}
If ($ location ['region'] = "CZ88.NET "){
$ Location ['region'] = "";
}
Return $ location;
}

/**
* Destructor used to automatically close opened files after page execution.
*
*/
Function _ desctruct (){
If ($ this-> fp ){
Fclose ($ this-> fp );
}
$ This-> fp = 0;
}
}
?>

This can also be downloaded from the Internet or copied here, which is also comprehensive.
Execution file. Here is the ip_location.php file.
Copy codeThe Code is as follows: <? Php
Function getIpPlace (){
Require_once ("IpLocation. php") // load the class file IpLocation. php
$ Ipfile = "qqwry. dat"; // obtain the information file of the region corresponding to the ip address
$ Iplocation = new IpLocation ($ ipfile); // new IpLocation ($ ipfile) $ ipfile ip address corresponds to the region information file
$ Ipresult = $ iplocation-> getlocation ("ip address"); // obtain the region getlocation ("ip region") based on the ip address ")
Return $ ipresult;
}
Print_r ($ getIpPlace (); // CALL THE METHOD
?>

Related Article

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.