PHP根据IP跳转不同城市代码

使用时首先实例化IPAddress类,然后调用getAddress()方法就可以返回对应的城市。具体代码如下:
<?php


  class IPAddress {
      function convertIP($ip) {                       
        $data_path = 'ip.dat';                                            //IP数据文件路径,IP数据库请自行搜索
        if(!ereg("^([0-9]{1,3}.){3}[0-9]{1,3}$", $ip)){                              //检查IP地址
              return 'IP Address Error';
        }
     
      if(!$fd = @fopen($data_path, 'rb')){                                                    //打开IP数据文件
              return 'IP date file not exists or access denied';
      }
     
      $ip = explode('.' , $ip);                                                                          //分解IP进行运算,得出整形数
      $ipNum = $ip[0] * 16777216 + $ip[1] * 65536 + $ip[2] * 256 + $ip[3];
     
      //获取IP数据索引开始和结束位置
      $DataBegin = fread($fd , 4);
      $DataEnd = fread($fd , 4);
      $ipbegin = implode('', unpack('L', $DataBegin));
      if($ipbegin < 0) $ipbegin += pow(2, 32);
      $ipend = implode('', unpack('L', $DataEnd));
      if($ipend < 0) $ipend += pow(2, 32);
      $ipAllNum = ($ipend - $ipbegin) / 7 + 1;
      $BeginNum = 0;
      $EndNum = $ipAllNum;
     
      //二分查找匹配的IP记录
      while($ip1num>$ipNum || $ip2num<$ipNum) {
              $Middle= intval(($EndNum + $BeginNum) / 2);
             
              //偏移指针到索引位置读取4个字节
              fseek($fd, $ipbegin + 7 * $Middle);
              $ipData1 = fread($fd , 4);
              if(strlen($ipData1) < 4) {
                      fclose($fd);
                      return 'System Error';
              }
              //提取出来的数据转换成长整形如果数据是负数则加上2的32次幂
              $ip1num = implode('', unpack('L', $ipData1));
              if($ip1num < 0) $ip1num += pow(2 , 32);
             
              //提取的长整型数大于我们IP地址则修改结束位置进行下一次循环
              if($ip1num > $ipNum) {
                      $EndNum = $Middle;
                      continue;
              }
              //取完上一个索引后取下一个索引
              $DataSeek = fread($fd, 3);
              if(strlen($DataSeek) < 3) {
                      fclose($fd);
                      return 'System Error';
              }
              $DataSeek = implode('', unpack('L', $DataSeek.chr(0)));
              fseek($fd, $DataSeek);
              $ipData2 = fread($fd, 4);
              if(strlen($ipData2) < 4) {
                      fclose($fd);
                      return 'System Error';
              }
              $ip2num = implode('', unpack('L', $ipData2));
              if($ip2num < 0) $ip2num += pow(2, 32);
              //没找到提示未知
              if($ip2num < $ipNum) {
                      if($Middle == $BeginNum) {
                              fclose($fd);
                              return 'Unknown';
                      }
                      $BeginNum = $Middle;
              }
      }
     
      $ipFlag = fread($fd, 1);
      if($ipFlag == chr(1)) {
              $ipSeek = fread($fd, 3);
              if(strlen($ipSeek) < 3) {
                      fclose($fd);
                      return 'System Error';
              }
              $ipSeek = implode('', unpack('L', $ipSeek.chr(0)));
              fseek($fd, $ipSeek);
              $ipFlag = fread($fd, 1);
      }
      if($ipFlag == chr(2)) {
              $AddrSeek = fread($fd, 3);
              if(strlen($AddrSeek) < 3) {
                      fclose($fd);
                      return 'System Error';
              }
              $ipFlag = fread($fd, 1);
              if($ipFlag == chr(2)) {
                      $AddrSeek2 = fread($fd, 3);
                      if(strlen($AddrSeek2) < 3) {
                              fclose($fd);
                              return 'System Error';
                      }
                      $AddrSeek2 = implode('', unpack('L', $AddrSeek2.chr(0)));
                      fseek($fd, $AddrSeek2);
              } else {
                      fseek($fd, -1, SEEK_CUR);
              }
              while(($char = fread($fd, 1)) != chr(0))
                      $ipAddr2 .= $char;
              $AddrSeek = implode('', unpack('L', $AddrSeek.chr(0)));
              fseek($fd, $AddrSeek);
              while(($char = fread($fd, 1)) != chr(0))
                      $ipAddr1 .= $char;
      } else {
              fseek($fd, -1, SEEK_CUR);
              while(($char = fread($fd, 1)) != chr(0))
                      $ipAddr1 .= $char;
              $ipFlag = fread($fd, 1);
              if($ipFlag == chr(2)) {
                      $AddrSeek2 = fread($fd, 3);
                      if(strlen($AddrSeek2) < 3) {
                              fclose($fd);
                              return 'System Error';
                      }
                      $AddrSeek2 = implode('', unpack('L', $AddrSeek2.chr(0)));
                      fseek($fd, $AddrSeek2);
              } else {
                      fseek($fd, -1, SEEK_CUR);
              }
              while(($char = fread($fd, 1)) != chr(0)){
                      $ipAddr2 .= $char;
              }
      }
            fclose($fd);
            //做相应的替换操作后返回结果
            if(preg_match('/http/i', $ipAddr2)) {
                    $ipAddr2 = '';
            }
            $ipaddr = "$ipAddr1 $ipAddr2";
            $ipaddr = preg_replace('/CZ88.Net/is' , '', $ipaddr);
            $ipaddr = preg_replace('/^s*/is', '', $ipaddr);
            $ipaddr = preg_replace('/s*$/is', '', $ipaddr);
            if(preg_match('/http/i', $ipaddr) || $ipaddr == '') {
                    $ipaddr = 'Unknown';
            }
            $ipaddr = iconv("gb2312","utf-8",$ipaddr);
            return $ipaddr;
      }
     
      function getAddress() {
            //获取客户端真实IP地址
            $user_IP = ($_SERVER["HTTP_VIA"]) ? $_SERVER["HTTP_X_FORWARDED_FOR"] : $_SERVER["REMOTE_ADDR"];
              $user_IP = ($user_IP) ? $user_IP : $_SERVER["REMOTE_ADDR"];
              return $this->convertIP($user_IP);
      }
}
?>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值