IP location query
-
- /**
- File name: IpLocation. class. php
- * IP location query class (I uploaded the main file and a test file, I uploaded it, and a QQWry. dat, which can be downloaded from the pure IP library, is too large to be uploaded here)
- *
- * @ Author Ma Bingyao
- * @ Version 1.5
- * @ Copyright 2005 CoolCode. CN
- */
- Class IpLocation {
- /**
- * QQWry. Dat file pointer
- * @ Var resource
- */
- Var $ fp;
- /**
- * Offset address of the first IP record
- * @ Var int
- */
- Var $ firstip;
- /**
- * Offset address of the last IP record
- * @ Var int
- */
- Var $ lastip;
- /**
- * Total number of IP records (excluding version Records)
- * @ Var int
- */
- Var $ totalip;
- /**
- * Constructor: Open the QQWry. Dat file and initialize 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 can be executed at the end of program execution
- Register_shutdown_function (array (& $ this, '_ construct '));
- }
- }
- /**
- * Returns the number of long integers read.
- * @ Access private
- * @ Return int
- */
- 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
- */
- 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
- */
- 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
- */
- 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 $ data;
- }
- /**
- * Returned region information
- *
- * @ Access private
- * @ Return string
- */
- 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;
- }
- }
- ?>
- Require_once ('iplocation. class. php ');
- $ Ip = '1970. 0.0.1 ';
- $ IdADDR = new IpLocation ();
- Print_r ($ idADDR-> getlocation ($ ip ));
- ?>
-
- /**
- * IP location query
- *
- * @ Author Ma Bingyao
- * @ Version 1.5
- * @ Copyright 2005 CoolCode. CN
- */
- Class IpLocation {
- /**
- * QQWry. Dat file pointer
- * @ Var resource
- */
- Var $ fp;
- /**
- * Offset address of the first IP record
- * @ Var int
- */
- Var $ firstip;
- /**
- * Offset address of the last IP record
- * @ Var int
- */
- Var $ lastip;
- /**
- * Total number of IP records (excluding version Records)
- * @ Var int
- */
- Var $ totalip;
- /**
- * Constructor: Open the QQWry. Dat file and initialize 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 can be executed at the end of program execution
- Register_shutdown_function (array (& $ this, '_ construct '));
- }
- }
- /**
- * Returns the number of long integers read.
- * @ Access private
- * @ Return int
- */
- 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
- */
- 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
- */
- 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
- */
- 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 $ data;
- }
- /**
- * Returned region information
- *
- * @ Access private
- * @ Return string
- */
- 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;
- }
- }
- ?>
|