php读取纯真ip数据库使用示例


Posted in PHP onJanuary 26, 2014
<?php
/*--------------------------------------------------
 ip2address [qqwry.dat]
--------------------------------------------------*/
class ip {
 var $fh; //IP数据库文件句柄
 var $first; //第一条索引
 var $last; //最后一条索引
 var $total; //索引总数
 //构造函数
 function __construct() {
  $this->fh = fopen('qqwry.dat', 'rb'); //qqwry.dat文件
  $this->first = $this->getLong4();
  $this->last = $this->getLong4();
  $this->total = ($this->last - $this->first) / 7; //每条索引7字节
 }
 //检查IP合法性
 function checkIp($ip) {
  $arr = explode('.',$ip);
  if(count($arr) !=4 ) {
   return false;
  } else {
   for ($i=0; $i < 4; $i++) {
    if ($arr[$i] <'0' || $arr[$i] > '255') {
     return false;
    }
   }
  }
  return true;
 }
 function getLong4() {
  //读取little-endian编码的4个字节转化为长整型数
  $result = unpack('Vlong', fread($this->fh, 4));
  return $result['long'];
 }
 function getLong3() {
  //读取little-endian编码的3个字节转化为长整型数
  $result = unpack('Vlong', fread($this->fh, 3).chr(0));
  return $result['long'];
 }
 //查询信息
 function getInfo($data = "") {
  $char = fread($this->fh, 1);
  while (ord($char) != 0) { //国家地区信息以0结束
   $data .= $char;
   $char = fread($this->fh, 1);
  }
  return $data;
 }
 //查询地区信息
 function getArea() {
  $byte = fread($this->fh, 1); //标志字节
  switch (ord($byte)) {
   case 0: $area = ''; break; //没有地区信息
   case 1: //地区被重定向
    fseek($this->fh, $this->getLong3());
    $area = $this->getInfo(); break;
   case 2: //地区被重定向
   fseek($this->fh, $this->getLong3());
   $area = $this->getInfo(); break;
   default: $area = $this->getInfo($byte);  break; //地区没有被重定向
  }
  return $area;
 }
 function ip2addr($ip) {
  if(!$this -> checkIp($ip)){
   return false;
  }
  $ip = pack('N', intval(ip2long($ip)));
  //二分查找
  $l = 0;
  $r = $this->total;
  while($l <= $r) {
   $m = floor(($l + $r) / 2); //计算中间索引
   fseek($this->fh, $this->first + $m * 7);
   $beginip = strrev(fread($this->fh, 4)); //中间索引的开始IP地址
   fseek($this->fh, $this->getLong3());
   $endip = strrev(fread($this->fh, 4)); //中间索引的结束IP地址
   if ($ip < $beginip) { //用户的IP小于中间索引的开始IP地址时
    $r = $m - 1;
   } else {
    if ($ip > $endip) { //用户的IP大于中间索引的结束IP地址时
     $l = $m + 1;
    } else { //用户IP在中间索引的IP范围内时
     $findip = $this->first + $m * 7;
     break;
    }
   }
  }
  //查询国家地区信息
  fseek($this->fh, $findip);
  $location['beginip'] = long2ip($this->getLong4()); //用户IP所在范围的开始地址
  $offset = $this->getlong3();
  fseek($this->fh, $offset);
  $location['endip'] = long2ip($this->getLong4()); //用户IP所在范围的结束地址
  $byte = fread($this->fh, 1); //标志字节
  switch (ord($byte)) {
   case 1:  //国家和区域信息都被重定向
    $countryOffset = $this->getLong3(); //重定向地址
    fseek($this->fh, $countryOffset);
    $byte = fread($this->fh, 1); //标志字节
    switch (ord($byte)) {
     case 2: //国家信息被二次重定向
      fseek($this->fh, $this->getLong3());
      $location['country'] = $this->getInfo();
      fseek($this->fh, $countryOffset + 4);
      $location['area'] = $this->getArea();
      break;
     default: //国家信息没有被二次重定向
      $location['country'] = $this->getInfo($byte);
      $location['area'] = $this->getArea();
      break;
    }
    break;
   case 2: //国家信息被重定向
    fseek($this->fh, $this->getLong3());
    $location['country'] = $this->getInfo();
    fseek($this->fh, $offset + 8);
    $location['area'] = $this->getArea();
    break;
   default: //国家信息没有被重定向
    $location['country'] = $this->getInfo($byte);
    $location['area'] = $this->getArea();
    break;
  }
  //gb2312 to utf-8(去除无信息时显示的CZ88.NET)
  foreach ($location as $k => $v) {
   $location[$k] = str_replace('CZ88.NET','',iconv('gb2312', 'utf-8', $v));
  }
  return $location;
 }
 //析构函数
 function __destruct() {
  fclose($this->fh);
 }
}
$ip = new ip();
$addr = $ip -> ip2addr('IP地址');
print_r($addr);
?>
PHP 相关文章推荐
CodeIgniter实现更改view文件夹路径的方法
Jul 04 PHP
php中in_array函数用法分析
Nov 15 PHP
php中getservbyport与getservbyname函数用法实例
Nov 18 PHP
php使用类继承解决代码重复的问题
Feb 11 PHP
PHP IDE phpstorm 常用快捷键
May 18 PHP
PHP简单读取PDF页数的实现方法
Jul 21 PHP
PHP获取当前URL路径的处理方法(适用于多条件筛选列表)
Feb 10 PHP
PHP程序员学习使用Swoole的理由
Jun 24 PHP
PHP使用glob方法遍历文件夹下所有文件的实例
Oct 17 PHP
定位地理位置PHP判断员工打卡签到经纬度是否在打卡之内
May 23 PHP
php实例化对象的实例方法
Nov 17 PHP
tp5使用layui实现多个图片上传(带附件选择)的方法实例
Nov 17 PHP
curl不使用文件存取cookie php使用curl获取cookie示例
Jan 26 #PHP
php版小黄鸡simsimi聊天机器人接口分享
Jan 26 #PHP
百度ping方法使用示例 自动ping百度
Jan 26 #PHP
PHP弹出提示框并跳转到新页面即重定向到新页面
Jan 24 #PHP
header导出Excel应用示例
Jan 24 #PHP
使用openssl实现rsa非对称加密算法示例
Jan 24 #PHP
测试php连接mysql是否成功的代码分享
Jan 24 #PHP
You might like
编译问题
2006/10/09 PHP
如何使用脚本模仿登陆过程
2006/11/22 PHP
php中使用addslashes函数报错问题的解决方法
2013/02/06 PHP
PHP命名空间(namespace)的使用基础及示例
2014/08/18 PHP
PHP命名空间与自动加载机制的基础介绍
2019/08/25 PHP
js获取图片长和宽度的代码
2009/11/24 Javascript
JS去除字符串两端空格的简单实例
2013/12/27 Javascript
jquery form 隐藏的input 选择
2014/04/29 Javascript
ext中store.load跟store.reload的区别示例介绍
2014/06/17 Javascript
jQuery复制节点用法示例(clone方法)
2016/09/08 Javascript
bootstrap table 表格中增加下拉菜单末行出现滚动条的快速解决方法
2017/01/05 Javascript
Bootstrap 3 按钮标签实例代码
2017/02/21 Javascript
easyui-datagrid特殊字符不能显示的处理方法
2017/04/12 Javascript
JS实现闭包中的沙箱模式示例
2017/09/07 Javascript
vue组件父与子通信详解(一)
2017/11/07 Javascript
Angular @HostBinding()和@HostListener()用法
2018/03/05 Javascript
细述Javascript的加法运算符的具体使用
2019/10/18 Javascript
Vue.js的模板语法详解
2020/02/16 Javascript
django 自定义用户user模型的三种方法
2014/11/18 Python
Python字符串中查找子串小技巧
2015/04/10 Python
python实现创建新列表和新字典,并使元素及键值对全部变成小写
2019/01/15 Python
Python 实现一个手机号码获取妹子名字的功能
2019/09/25 Python
python实现PDF中表格转化为Excel的方法
2020/06/16 Python
详解Python 中的容器 collections
2020/08/17 Python
前端实现背景虚化但内容清晰且自适应 的实例代码
2019/08/01 HTML / CSS
波兰补充商店:Muscle Power
2018/10/29 全球购物
越南综合购物网站:Lazada越南
2019/06/10 全球购物
创建索引时需要注意的事项
2013/05/13 面试题
幼儿园秋游活动方案
2014/01/21 职场文书
终止合同协议书
2014/04/17 职场文书
计算机售后服务承诺书
2014/05/30 职场文书
运动会口号8字
2014/06/07 职场文书
光棍节联谊晚会活动策划书
2014/10/10 职场文书
2014年教育培训工作总结
2014/12/08 职场文书
2019 入党申请书范文
2019/07/10 职场文书
vue3种table表格选项个数的控制方法
2022/04/14 Vue.js