IP geolocation Query class
-
- /**
- File name: IpLocation.class.php
- * IP Geo-Location query class (Master file I'm uploading it.) I upload a test file, and there is a QQWry.Dat this can be downloaded to the pure IP library because there are more than 6M so here do not upload it up.
- *
- * @author Ma Bingyao
- * @version 1.5
- * @copyright 2005 coolcode.cn
- */
- Class Iplocation {
- /**
- * QQWry.Dat file pointer
- * @var Resource
- */
- var $fp;
- /**
- * The offset address of the first IP record
- * @var int
- */
- var $firstip;
- /**
- * Offset address of last IP record
- * @var int
- */
- var $lastip;
- /**
- * Total number of IP records (not including version information Records)
- * @var int
- */
- var $totalip;
- /**
- * constructor to open the QQWry.Dat file and initialize the information in the class
- * @param string $filename
- * @return Iplocation
- */
- 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;
- Register the destructor so that it executes at the end of the program execution
- Register_shutdown_function (Array (& $this, ' __construct '));
- }
- }
- /**
- * Returns the number of read long integers
- * @access Private
- * @return int
- */
- function Getlong () {
- Converts the Read Little-endian encoded 4 bytes to a long integer number
- $result = Unpack (' Vlong ', fread ($this->FP, 4));
- return $result [' Long '];
- }
- /**
- * Returns the number of 3-byte long integers read
- *
- * @access Private
- * @return int
- */
- function Getlong3 () {
- Converts the Read Little-endian encoded 3 bytes to a long integer number
- $result = Unpack (' Vlong ', fread ($this->FP, 3). chr (0));
- return $result [' Long '];
- }
- /**
- * Returns the IP address that can be compared after compression
- *
- * @access Private
- * @param string $ip
- * @return String
- */
- function Packip ($IP) {
- Converts the IP address to a long integer and returns false if the IP address is incorrect in PHP5.
- At this point intval converts the flase to an integer-1, which is then compressed into Big-endian encoded string
- Return pack (' N ', Intval (Ip2long ($IP)));
- }
- /**
- * Returns the Read string
- *
- * @access Private
- * @param string $data
- * @return String
- */
- function GetString ($data = "") {
- $char = Fread ($this->fp, 1);
- while (Ord ($char) > 0) {//string is saved in C format and ends in
- $data. = $char; Connect prompt the read word after the given string
- $char = Fread ($this->fp, 1);
- }
- return $data;
- }
- /**
- * Return Area information
- *
- * @access Private
- * @return String
- */
- function Getarea () {
- $byte = Fread ($this->fp, 1); Flag byte
- Switch (ord ($byte)) {
- Case 0://No area information
- $area = "";
- Break
- Case 1:
- Case 2://Flag byte 1 or 2 indicating that the zone information is redirected
- Fseek ($this->fp, $this->getlong3 ());
- $area = $this->getstring ();
- Break
- Default://Otherwise, indicates that the zone information has not been redirected
- $area = $this->getstring ($byte);
- Break
- }
- return $area;
- }
- /**
- * Return the region information according to the IP address or domain name given
- * @access Public
- * @param string $ip
- * @return Array
- */
- function GetLocation ($IP) {
- if (! $this->FP) return null; If the data file is not opened correctly, return empty
- $location [' ip '] = gethostbyname ($IP); Convert the entered domain name to an IP address
- $ip = $this->packip ($location [' IP ']); Convert the IP address you entered into a comparable IP address
- Illegal IP address will be converted to 255.255.255.255
- Search by split
- $l = 0; The bottom boundary of the search
- $u = $this->totalip; Top boundary of search
- $findip = $this->lastip; Returns the last IP record (version information for QQWry.Dat) if it is not found
- while ($l <= $u) {//when the upper boundary is less than the lower boundary, the lookup fails
- $i = Floor (($l + $u)/2); Calculate approximate intermediate records
- Fseek ($this->fp, $this->firstip + $i * 7);
- $beginip = Strrev (fread ($this->FP, 4)); Gets the start IP address of the intermediate record
- The purpose of the Strrev function here is to convert the Little-endian's compressed IP address into a Big-endian format.
- To be used for comparison, the same later.
- if ($ip < $beginip) {//user's IP is smaller than the intermediate record's start IP address
- $u = $i-1; Modify the top boundary of the search to the intermediate record minus one
- } else {
- Fseek ($this->fp, $this->getlong3 ());
- $endip = Strrev (fread ($this->FP, 4)); Gets the end IP address of the 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 {//The IP of the user is within the IP range of the intermediate record
- $findip = $this->firstip + $i * 7;
- Break Indicates that the result is found and exits the loop
- }
- }
- }
- Get the IP geolocation information that was found
- Fseek ($this->fp, $findip);
- $location [' beginip '] = Long2ip ($this->getlong ()); Start address of the range where the user IP is located
- $offset = $this->getlong3 ();
- Fseek ($this->fp, $offset);
- $location [' endip '] = Long2ip ($this->getlong ()); End address of the range where the user IP is located
- $byte = Fread ($this->fp, 1); Flag byte
- Switch (ord ($byte)) {
- Case 1://Flag byte 1, indicating that national and regional information is being 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://Flag Byte is 2, indicating that the country information is redirected again
- 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 the country 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 means no valid information
- $location [' country '] = "Unknown";
- }
- if ($location [' area '] = = "Cz88.net") {
- $location [' area '] = "";
- }
- return $location;
- }
- /**
- * destructor to automatically close open files after the page execution ends.
- *
- */
- function __desctruct () {
- if ($this->fp) {
- Fclose ($this->FP);
- }
- $this->FP = 0;
- }
- }
- ?>
Copy Code
- Require_once (' IpLocation.class.php ');
- $ip = ' 127.0.0.1 ';
- $idADDR =new iplocation ();
- Print_r ($idADDR->getlocation ($IP));
- ?>
Copy Code
-
- /**
- * IP geolocation Query class
- *
- * @author Ma Bingyao
- * @version 1.5
- * @copyright 2005 coolcode.cn
- */
- Class Iplocation {
- /**
- * QQWry.Dat file pointer
- * @var Resource
- */
- var $fp;
- /**
- * The offset address of the first IP record
- * @var int
- */
- var $firstip;
- /**
- * Offset address of last IP record
- * @var int
- */
- var $lastip;
- /**
- * Total number of IP records (not including version information Records)
- * @var int
- */
- var $totalip;
- /**
- * constructor to open the QQWry.Dat file and initialize the information in the class
- * @param string $filename
- * @return Iplocation
- */
- 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;
- Register the destructor so that it executes at the end of the program execution
- Register_shutdown_function (Array (& $this, ' __construct '));
- }
- }
- /**
- * Returns the number of read long integers
- * @access Private
- * @return int
- */
- function Getlong () {
- Converts the Read Little-endian encoded 4 bytes to a long integer number
- $result = Unpack (' Vlong ', fread ($this->FP, 4));
- return $result [' Long '];
- }
- /**
- * Returns the number of 3-byte long integers read
- *
- * @access Private
- * @return int
- */
- function Getlong3 () {
- Converts the Read Little-endian encoded 3 bytes to a long integer number
- $result = Unpack (' Vlong ', fread ($this->FP, 3). chr (0));
- return $result [' Long '];
- }
- /**
- * Returns the IP address that can be compared after compression
- *
- * @access Private
- * @param string $ip
- * @return String
- */
- function Packip ($IP) {
- Converts the IP address to a long integer and returns false if the IP address is incorrect in PHP5.
- At this point intval converts the flase to an integer-1, which is then compressed into Big-endian encoded string
- Return pack (' N ', Intval (Ip2long ($IP)));
- }
- /**
- * Returns the Read string
- *
- * @access Private
- * @param string $data
- * @return String
- */
- function GetString ($data = "") {
- $char = Fread ($this->fp, 1);
- while (Ord ($char) > 0) {//string is saved in C format and ends in
- $data. = $char; Connect prompt the read word after the given string
- $char = Fread ($this->fp, 1);
- }
- return $data;
- }
- /**
- * Return Area information
- *
- * @access Private
- * @return String
- */
- function Getarea () {
- $byte = Fread ($this->fp, 1); Flag byte
- Switch (ord ($byte)) {
- Case 0://No area information
- $area = "";
- Break
- Case 1:
- Case 2://Flag byte 1 or 2 indicating that the zone information is redirected
- Fseek ($this->fp, $this->getlong3 ());
- $area = $this->getstring ();
- Break
- Default://Otherwise, indicates that the zone information has not been redirected
- $area = $this->getstring ($byte);
- Break
- }
- return $area;
- }
- /**
- * Return the region information according to the IP address or domain name given
- * @access Public
- * @param string $ip
- * @return Array
- */
- function GetLocation ($IP) {
- if (! $this->FP) return null; If the data file is not opened correctly, return empty
- $location [' ip '] = gethostbyname ($IP); Convert the entered domain name to an IP address
- $ip = $this->packip ($location [' IP ']); Convert the IP address you entered into a comparable IP address
- Illegal IP address will be converted to 255.255.255.255
- Search by split
- $l = 0; The bottom boundary of the search
- $u = $this->totalip; Top boundary of search
- $findip = $this->lastip; Returns the last IP record (version information for QQWry.Dat) if it is not found
- while ($l <= $u) {//when the upper boundary is less than the lower boundary, the lookup fails
- $i = Floor (($l + $u)/2); Calculate approximate intermediate records
- Fseek ($this->fp, $this->firstip + $i * 7);
- $beginip = Strrev (fread ($this->FP, 4)); Gets the start IP address of the intermediate record
- The purpose of the Strrev function here is to convert the Little-endian's compressed IP address into a Big-endian format.
- To be used for comparison, the same later.
- if ($ip < $beginip) {//user's IP is smaller than the intermediate record's start IP address
- $u = $i-1; Modify the top boundary of the search to the intermediate record minus one
- } else {
- Fseek ($this->fp, $this->getlong3 ());
- $endip = Strrev (fread ($this->FP, 4)); Gets the end IP address of the 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 {//The IP of the user is within the IP range of the intermediate record
- $findip = $this->firstip + $i * 7;
- Break Indicates that the result is found and exits the loop
- }
- }
- }
- Get the IP geolocation information that was found
- Fseek ($this->fp, $findip);
- $location [' beginip '] = Long2ip ($this->getlong ()); Start address of the range where the user IP is located
- $offset = $this->getlong3 ();
- Fseek ($this->fp, $offset);
- $location [' endip '] = Long2ip ($this->getlong ()); End address of the range where the user IP is located
- $byte = Fread ($this->fp, 1); Flag byte
- Switch (ord ($byte)) {
- Case 1://Flag byte 1, indicating that national and regional information is being 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://Flag Byte is 2, indicating that the country information is redirected again
- 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 the country 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 means no valid information
- $location [' country '] = "Unknown";
- }
- if ($location [' area '] = = "Cz88.net") {
- $location [' area '] = "";
- }
- return $location;
- }
- /**
- * destructor to automatically close open files after the page execution ends.
- *
- */
- function __desctruct () {
- if ($this->fp) {
- Fclose ($this->FP);
- }
- $this->FP = 0;
- }
- }
- ?>
Copy Code |