Provide an IP address geographic location query class again

Source: Internet
Author: User
Tags comparable
Provide an IP address geographic location query class again
IP location query

  1. /**
  2. File name: IpLocation. class. php
  3. * 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)
  4. *
  5. * @ Author Ma Bingyao
  6. * @ Version 1.5
  7. * @ Copyright 2005 CoolCode. CN
  8. */
  9. Class IpLocation {
  10. /**
  11. * QQWry. Dat file pointer
  12. * @ Var resource
  13. */
  14. Var $ fp;
  15. /**
  16. * Offset address of the first IP record
  17. * @ Var int
  18. */
  19. Var $ firstip;
  20. /**
  21. * Offset address of the last IP record
  22. * @ Var int
  23. */
  24. Var $ lastip;
  25. /**
  26. * Total number of IP records (excluding version Records)
  27. * @ Var int
  28. */
  29. Var $ totalip;
  30. /**
  31. * Constructor: Open the QQWry. Dat file and initialize information in the class.
  32. * @ Param string $ filename
  33. * @ Return IpLocation
  34. */
  35. Function _ construct ($ filename = "QQWry. Dat "){
  36. $ This-> fp = 0;
  37. If ($ this-> fp = @ fopen ($ filename, 'RB '))! = False ){
  38. $ This-> firstip = $ this-> getlong ();
  39. $ This-> lastip = $ this-> getlong ();
  40. $ This-> totalip = ($ this-> lastip-$ this-> firstip)/7;
  41. // Register the destructor so that it can be executed at the end of program execution
  42. Register_shutdown_function (array (& $ this, '_ construct '));
  43. }
  44. }
  45. /**
  46. * Returns the number of long integers read.
  47. * @ Access private
  48. * @ Return int
  49. */
  50. Function getlong (){
  51. // Convert the 4 bytes of the read little-endian encoding to the long integer
  52. $ Result = unpack ('vlong', fread ($ this-> fp, 4 ));
  53. Return $ result ['long'];
  54. }
  55. /**
  56. * Returns the number of long integers read in three bytes.
  57. *
  58. * @ Access private
  59. * @ Return int
  60. */
  61. Function getlong3 (){
  62. // Convert the three bytes of the read little-endian encoding into a long integer.
  63. $ Result = unpack ('vlong', fread ($ this-> fp, 3). chr (0 ));
  64. Return $ result ['long'];
  65. }
  66. /**
  67. * Return the IP addresses that can be compared after compression.
  68. *
  69. * @ Access private
  70. * @ Param string $ ip
  71. * @ Return string
  72. */
  73. Function packip ($ ip ){
  74. // Convert the IP address to a long integer. if the IP address is incorrect in PHP5, False is returned,
  75. // At this time, intval converts Flase to an integer-1, and then compresses it into a string encoded by big-endian.
  76. Return pack ('N', intval (ip2long ($ ip )));
  77. }
  78. /**
  79. * Returns the read string.
  80. *
  81. * @ Access private
  82. * @ Param string $ data
  83. * @ Return string
  84. */
  85. Function getstring ($ data = ""){
  86. $ Char = fread ($ this-> fp, 1 );
  87. While (ord ($ char)> 0) {// string is saved in C format and ended with \ 0
  88. $ Data. = $ char; // after connecting the read characters to the given string
  89. $ Char = fread ($ this-> fp, 1 );
  90. }
  91. Return $ data;
  92. }
  93. /**
  94. * Returned region information
  95. *
  96. * @ Access private
  97. * @ Return string
  98. */
  99. Function getarea (){
  100. $ Byte = fread ($ this-> fp, 1); // flag byte
  101. Switch (ord ($ byte )){
  102. Case 0: // no region information
  103. $ Area = "";
  104. Break;
  105. Case 1:
  106. Case 2: // indicates that the region information is redirected when the byte is 1 or 2.
  107. Fseek ($ this-> fp, $ this-> getlong3 ());
  108. $ Area = $ this-> getstring ();
  109. Break;
  110. Default: // otherwise, the region information is not redirected.
  111. $ Area = $ this-> getstring ($ byte );
  112. Break;
  113. }
  114. Return $ area;
  115. }
  116. /**
  117. * Return region information based on the given IP address or domain name
  118. * @ Access public
  119. * @ Param string $ ip
  120. * @ Return array
  121. */
  122. Function getlocation ($ ip ){
  123. If (! $ This-> fp) return null; // if the data file is not properly opened, null is returned directly.
  124. $ Location ['IP'] = gethostbyname ($ ip); // Convert the entered domain name to an ip address
  125. $ Ip = $ this-> packip ($ location ['IP']); // convert the input ip address to a comparable ip address.
  126. // Invalid IP address will be converted to 255.255.255.255
  127. // Split Search
  128. $ L = 0; // bottom boundary of the search
  129. $ U = $ this-> totalip; // The upper boundary of the search
  130. $ Findip = $ this-> lastip; // if not found, the last IP record is returned (QQWry. Dat version information)
  131. While ($ l <= $ u) {// when the boundary is smaller than the bottom boundary, the search fails.
  132. $ I = floor ($ l + $ u)/2); // calculate the approximate intermediate record
  133. Fseek ($ this-> fp, $ this-> firstip + $ I * 7 );
  134. $ Beginip = strrev (fread ($ this-> fp, 4); // Obtain the starting IP address of the intermediate record
  135. // The strrev function is used to convert the compressed IP address of little-endian to the big-endian format.
  136. // Used for comparison.
  137. If ($ ip <$ beginip) {// when the user's IP address is smaller than the starting ip address of the intermediate record
  138. $ U = $ I-1; // change the upper boundary of the search to minus one for the intermediate record
  139. } Else {
  140. Fseek ($ this-> fp, $ this-> getlong3 ());
  141. $ Endip = strrev (fread ($ this-> fp, 4); // Obtain the end IP address of the intermediate record
  142. If ($ ip> $ endip) {// when the user's IP address is greater than the end ip address of the intermediate record
  143. $ L = $ I + 1; // change the bottom boundary of the search to an intermediate record plus one
  144. } Else {// when the user's IP address is within the IP address range recorded in the middle
  145. $ Findip = $ this-> firstip + $ I * 7;
  146. Break; // indicates that the result is found and the loop is exited.
  147. }
  148. }
  149. }
  150. // Obtain the IP address location information.
  151. Fseek ($ this-> fp, $ findip );
  152. $ Location ['ininip'] = long2ip ($ this-> getlong (); // start address of the user's IP address range
  153. $ Offset = $ this-> getlong3 ();
  154. Fseek ($ this-> fp, $ offset );
  155. $ Location ['enabled'] = long2ip ($ this-> getlong (); // end address of the user's IP address range
  156. $ Byte = fread ($ this-> fp, 1); // flag byte
  157. Switch (ord ($ byte )){
  158. Case 1: // The flag byte is 1, indicating that both the country and region information are redirected at the same time.
  159. $ CountryOffset = $ this-> getlong3 (); // redirect address
  160. Fseek ($ this-> fp, $ countryOffset );
  161. $ Byte = fread ($ this-> fp, 1); // flag byte
  162. Switch (ord ($ byte )){
  163. Case 2: // The flag byte is 2, indicating that the country information is redirected.
  164. Fseek ($ this-> fp, $ this-> getlong3 ());
  165. $ Location ['country'] = $ this-> getstring ();
  166. Fseek ($ this-> fp, $ countryOffset + 4 );
  167. $ Location ['region'] = $ this-> getarea ();
  168. Break;
  169. Default: // otherwise, the country information is not redirected.
  170. $ Location ['country'] = $ this-> getstring ($ byte );
  171. $ Location ['region'] = $ this-> getarea ();
  172. Break;
  173. }
  174. Break;
  175. Case 2: // The flag byte is 2, indicating that the country information is redirected.
  176. Fseek ($ this-> fp, $ this-> getlong3 ());
  177. $ Location ['country'] = $ this-> getstring ();
  178. Fseek ($ this-> fp, $ offset + 8 );
  179. $ Location ['region'] = $ this-> getarea ();
  180. Break;
  181. Default: // otherwise, the country information is not redirected.
  182. $ Location ['country'] = $ this-> getstring ($ byte );
  183. $ Location ['region'] = $ this-> getarea ();
  184. Break;
  185. }
  186. If ($ location ['country'] = "CZ88.NET") {// CZ88.NET indicates no valid information
  187. $ Location ['country'] = "unknown ";
  188. }
  189. If ($ location ['region'] = "CZ88.NET "){
  190. $ Location ['region'] = "";
  191. }
  192. Return $ location;
  193. }
  194. /**
  195. * Destructor used to automatically close opened files after Page execution.
  196. *
  197. */
  198. Function _ desctruct (){
  199. If ($ this-> fp ){
  200. Fclose ($ this-> fp );
  201. }
  202. $ This-> fp = 0;
  203. }
  204. }
  205. ?>

  1. Require_once ('iplocation. class. php ');
  2. $ Ip = '1970. 0.0.1 ';
  3. $ IdADDR = new IpLocation ();
  4. Print_r ($ idADDR-> getlocation ($ ip ));
  5. ?>

  1. /**
  2. * IP location query
  3. *
  4. * @ Author Ma Bingyao
  5. * @ Version 1.5
  6. * @ Copyright 2005 CoolCode. CN
  7. */
  8. Class IpLocation {
  9. /**
  10. * QQWry. Dat file pointer
  11. * @ Var resource
  12. */
  13. Var $ fp;
  14. /**
  15. * Offset address of the first IP record
  16. * @ Var int
  17. */
  18. Var $ firstip;
  19. /**
  20. * Offset address of the last IP record
  21. * @ Var int
  22. */
  23. Var $ lastip;
  24. /**
  25. * Total number of IP records (excluding version Records)
  26. * @ Var int
  27. */
  28. Var $ totalip;
  29. /**
  30. * Constructor: Open the QQWry. Dat file and initialize information in the class.
  31. * @ Param string $ filename
  32. * @ Return IpLocation
  33. */
  34. Function _ construct ($ filename = "QQWry. Dat "){
  35. $ This-> fp = 0;
  36. If ($ this-> fp = @ fopen ($ filename, 'RB '))! = False ){
  37. $ This-> firstip = $ this-> getlong ();
  38. $ This-> lastip = $ this-> getlong ();
  39. $ This-> totalip = ($ this-> lastip-$ this-> firstip)/7;
  40. // Register the destructor so that it can be executed at the end of program execution
  41. Register_shutdown_function (array (& $ this, '_ construct '));
  42. }
  43. }
  44. /**
  45. * Returns the number of long integers read.
  46. * @ Access private
  47. * @ Return int
  48. */
  49. Function getlong (){
  50. // Convert the 4 bytes of the read little-endian encoding to the long integer
  51. $ Result = unpack ('vlong', fread ($ this-> fp, 4 ));
  52. Return $ result ['long'];
  53. }
  54. /**
  55. * Returns the number of long integers read in three bytes.
  56. *
  57. * @ Access private
  58. * @ Return int
  59. */
  60. Function getlong3 (){
  61. // Convert the three bytes of the read little-endian encoding into a long integer.
  62. $ Result = unpack ('vlong', fread ($ this-> fp, 3). chr (0 ));
  63. Return $ result ['long'];
  64. }
  65. /**
  66. * Return the IP addresses that can be compared after compression.
  67. *
  68. * @ Access private
  69. * @ Param string $ ip
  70. * @ Return string
  71. */
  72. Function packip ($ ip ){
  73. // Convert the IP address to a long integer. if the IP address is incorrect in PHP5, False is returned,
  74. // At this time, intval converts Flase to an integer-1, and then compresses it into a string encoded by big-endian.
  75. Return pack ('N', intval (ip2long ($ ip )));
  76. }
  77. /**
  78. * Returns the read string.
  79. *
  80. * @ Access private
  81. * @ Param string $ data
  82. * @ Return string
  83. */
  84. Function getstring ($ data = ""){
  85. $ Char = fread ($ this-> fp, 1 );
  86. While (ord ($ char)> 0) {// string is saved in C format and ended with \ 0
  87. $ Data. = $ char; // after connecting the read characters to the given string
  88. $ Char = fread ($ this-> fp, 1 );
  89. }
  90. Return $ data;
  91. }
  92. /**
  93. * Returned region information
  94. *
  95. * @ Access private
  96. * @ Return string
  97. */
  98. Function getarea (){
  99. $ Byte = fread ($ this-> fp, 1); // flag byte
  100. Switch (ord ($ byte )){
  101. Case 0: // no region information
  102. $ Area = "";
  103. Break;
  104. Case 1:
  105. Case 2: // indicates that the region information is redirected when the byte is 1 or 2.
  106. Fseek ($ this-> fp, $ this-> getlong3 ());
  107. $ Area = $ this-> getstring ();
  108. Break;
  109. Default: // otherwise, the region information is not redirected.
  110. $ Area = $ this-> getstring ($ byte );
  111. Break;
  112. }
  113. Return $ area;
  114. }
  115. /**
  116. * Return region information based on the given IP address or domain name
  117. * @ Access public
  118. * @ Param string $ ip
  119. * @ Return array
  120. */
  121. Function getlocation ($ ip ){
  122. If (! $ This-> fp) return null; // if the data file is not properly opened, null is returned directly.
  123. $ Location ['IP'] = gethostbyname ($ ip); // Convert the entered domain name to an ip address
  124. $ Ip = $ this-> packip ($ location ['IP']); // convert the input ip address to a comparable ip address.
  125. // Invalid IP address will be converted to 255.255.255.255
  126. // Split Search
  127. $ L = 0; // bottom boundary of the search
  128. $ U = $ this-> totalip; // The upper boundary of the search
  129. $ Findip = $ this-> lastip; // if not found, the last IP record is returned (QQWry. Dat version information)
  130. While ($ l <= $ u) {// when the boundary is smaller than the bottom boundary, the search fails.
  131. $ I = floor ($ l + $ u)/2); // calculate the approximate intermediate record
  132. Fseek ($ this-> fp, $ this-> firstip + $ I * 7 );
  133. $ Beginip = strrev (fread ($ this-> fp, 4); // Obtain the starting IP address of the intermediate record
  134. // The strrev function is used to convert the compressed IP address of little-endian to the big-endian format.
  135. // Used for comparison.
  136. If ($ ip <$ beginip) {// when the user's IP address is smaller than the starting ip address of the intermediate record
  137. $ U = $ I-1; // change the upper boundary of the search to minus one for the intermediate record
  138. } Else {
  139. Fseek ($ this-> fp, $ this-> getlong3 ());
  140. $ Endip = strrev (fread ($ this-> fp, 4); // Obtain the end IP address of the intermediate record
  141. If ($ ip> $ endip) {// when the user's IP address is greater than the end ip address of the intermediate record
  142. $ L = $ I + 1; // change the bottom boundary of the search to an intermediate record plus one
  143. } Else {// when the user's IP address is within the IP address range recorded in the middle
  144. $ Findip = $ this-> firstip + $ I * 7;
  145. Break; // indicates that the result is found and the loop is exited.
  146. }
  147. }
  148. }
  149. // Obtain the IP address location information.
  150. Fseek ($ this-> fp, $ findip );
  151. $ Location ['ininip'] = long2ip ($ this-> getlong (); // start address of the user's IP address range
  152. $ Offset = $ this-> getlong3 ();
  153. Fseek ($ this-> fp, $ offset );
  154. $ Location ['enabled'] = long2ip ($ this-> getlong (); // end address of the user's IP address range
  155. $ Byte = fread ($ this-> fp, 1); // flag byte
  156. Switch (ord ($ byte )){
  157. Case 1: // The flag byte is 1, indicating that both the country and region information are redirected at the same time.
  158. $ CountryOffset = $ this-> getlong3 (); // redirect address
  159. Fseek ($ this-> fp, $ countryOffset );
  160. $ Byte = fread ($ this-> fp, 1); // flag byte
  161. Switch (ord ($ byte )){
  162. Case 2: // The flag byte is 2, indicating that the country information is redirected.
  163. Fseek ($ this-> fp, $ this-> getlong3 ());
  164. $ Location ['country'] = $ this-> getstring ();
  165. Fseek ($ this-> fp, $ countryOffset + 4 );
  166. $ Location ['region'] = $ this-> getarea ();
  167. Break;
  168. Default: // otherwise, the country information is not redirected.
  169. $ Location ['country'] = $ this-> getstring ($ byte );
  170. $ Location ['region'] = $ this-> getarea ();
  171. Break;
  172. }
  173. Break;
  174. Case 2: // The flag byte is 2, indicating that the country information is redirected.
  175. Fseek ($ this-> fp, $ this-> getlong3 ());
  176. $ Location ['country'] = $ this-> getstring ();
  177. Fseek ($ this-> fp, $ offset + 8 );
  178. $ Location ['region'] = $ this-> getarea ();
  179. Break;
  180. Default: // otherwise, the country information is not redirected.
  181. $ Location ['country'] = $ this-> getstring ($ byte );
  182. $ Location ['region'] = $ this-> getarea ();
  183. Break;
  184. }
  185. If ($ location ['country'] = "CZ88.NET") {// CZ88.NET indicates no valid information
  186. $ Location ['country'] = "unknown ";
  187. }
  188. If ($ location ['region'] = "CZ88.NET "){
  189. $ Location ['region'] = "";
  190. }
  191. Return $ location;
  192. }
  193. /**
  194. * Destructor used to automatically close opened files after Page execution.
  195. *
  196. */
  197. Function _ desctruct (){
  198. If ($ this-> fp ){
  199. Fclose ($ this-> fp );
  200. }
  201. $ This-> fp = 0;
  202. }
  203. }
  204. ?>

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.