Ip.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. <?php
  2. /*
  3. 全球 IPv4 地址归属地数据库(17MON.CN 版)
  4. 高春辉(pAUL gAO) <gaochunhui@gmail.com>
  5. Build 20141009 版权所有 17MON.CN
  6. (C) 2006 - 2014 保留所有权利
  7. 请注意及时更新 IP 数据库版本
  8. 数据问题请加 QQ 群: 346280296
  9. Code for PHP 5.3+ only
  10. */
  11. class Ip
  12. {
  13. private static $ip = NULL;
  14. private static $fp = NULL;
  15. private static $offset = NULL;
  16. private static $index = NULL;
  17. private static $cached = array();
  18. public static function find($ip)
  19. {
  20. if (empty($ip) === TRUE)
  21. {
  22. return 'N/A';
  23. }
  24. $nip = gethostbyname($ip);
  25. $ipdot = explode('.', $nip);
  26. if ($ipdot[0] < 0 || $ipdot[0] > 255 || count($ipdot) !== 4)
  27. {
  28. return 'N/A';
  29. }
  30. if (isset(self::$cached[$nip]) === TRUE)
  31. {
  32. return self::$cached[$nip];
  33. }
  34. if (self::$fp === NULL)
  35. {
  36. self::init();
  37. }
  38. $nip2 = pack('N', ip2long($nip));
  39. $tmp_offset = (int)$ipdot[0] * 4;
  40. $start = unpack('Vlen', self::$index[$tmp_offset] . self::$index[$tmp_offset + 1] . self::$index[$tmp_offset + 2] . self::$index[$tmp_offset + 3]);
  41. $index_offset = $index_length = NULL;
  42. $max_comp_len = self::$offset['len'] - 1024 - 4;
  43. for ($start = $start['len'] * 8 + 1024; $start < $max_comp_len; $start += 8)
  44. {
  45. if (self::$index[$start] . self::$index[$start + 1] . self::$index[$start + 2] . self::$index[$start + 3] >= $nip2)
  46. {
  47. $index_offset = unpack('Vlen', self::$index[$start + 4] . self::$index[$start + 5] . self::$index[$start + 6] . "\x0");
  48. $index_length = unpack('Clen', self::$index[$start + 7]);
  49. break;
  50. }
  51. }
  52. if ($index_offset === NULL)
  53. {
  54. return 'N/A';
  55. }
  56. fseek(self::$fp, self::$offset['len'] + $index_offset['len'] - 1024);
  57. self::$cached[$nip] = explode("\t", fread(self::$fp, $index_length['len']));
  58. return self::$cached[$nip];
  59. }
  60. private static function init()
  61. {
  62. if (self::$fp === NULL)
  63. {
  64. self::$ip = new self();
  65. self::$fp = fopen(__DIR__ . '/ip/17monipdb.dat', 'rb');
  66. if (self::$fp === FALSE)
  67. {
  68. throw new Exception('Invalid 17monipdb.dat file!');
  69. }
  70. self::$offset = unpack('Nlen', fread(self::$fp, 4));
  71. if (self::$offset['len'] < 4)
  72. {
  73. throw new Exception('Invalid 17monipdb.dat file!');
  74. }
  75. self::$index = fread(self::$fp, self::$offset['len'] - 4);
  76. }
  77. }
  78. public function __destruct()
  79. {
  80. if (self::$fp !== NULL)
  81. {
  82. fclose(self::$fp);
  83. }
  84. }
  85. }
  86. ?>