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 相关文章推荐
PHP中在数据库中保存Checkbox数据(2)
Oct 09 PHP
smarty静态实验表明,网络上是错的~呵呵
Nov 25 PHP
不错的一篇面向对象的PHP开发模式(简写版)
Mar 15 PHP
解析zend Framework如何自动加载类
Jun 28 PHP
destoon供应信息title调用出公司名称的方法
Aug 22 PHP
smarty实现多级分类的方法
Dec 05 PHP
验证坐标在某坐标区域内php代码
Oct 08 PHP
CI框架封装的常用图像处理方法(缩略图,水印,旋转,上传等)
Nov 22 PHP
php读取出一个文件夹及其子文件夹下所有文件的方法示例
Jun 15 PHP
详解PHP素材图片上传、下载功能
Apr 12 PHP
laravel-admin 中列表筛选方法
Oct 03 PHP
laravel 解决Eloquent ORM的save方法无法插入数据的问题
Oct 21 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
php结合ajax实现手机发红包的案例
2016/10/13 PHP
如何实现浏览器上的右键菜单
2006/07/10 Javascript
JavaScript语句可以不以;结尾的烦恼
2007/03/08 Javascript
jquery 与NVelocity 产生冲突的解决方法
2011/06/13 Javascript
JS中的prototype与面向对象的实例讲解
2013/05/22 Javascript
JS实现日期加减的方法
2013/11/29 Javascript
javaScript实现滚动新闻的方法
2015/07/30 Javascript
在javascript中随机数 math random如何生成指定范围数值的随机数
2015/10/21 Javascript
javascript对象的创建和访问
2016/03/08 Javascript
简单理解vue中el、template、replace元素
2016/10/27 Javascript
jQuery加密密码到cookie的实现代码
2017/04/18 jQuery
详解Angular2 关于*ngFor 嵌套循环
2017/05/22 Javascript
JS常用的几种数组遍历方式以及性能分析对比实例详解
2018/04/11 Javascript
mockjs+vue页面直接展示数据的方法
2018/12/19 Javascript
Vuex中的Mutations的具体使用方法
2020/06/01 Javascript
微信小程序整个页面的自动适应布局的实现
2020/07/12 Javascript
three.js 将图片马赛克化的示例代码
2020/07/31 Javascript
[01:00:44]DOTA2上海特级锦标赛主赛事日 - 3 败者组第三轮#1COL VS Alliance第三局
2016/03/04 DOTA
python删除列表内容
2015/08/04 Python
Python实现的递归神经网络简单示例
2017/08/11 Python
python中子类调用父类函数的方法示例
2017/08/18 Python
Python虚拟环境项目实例
2017/11/20 Python
python采集微信公众号文章
2018/12/20 Python
Python MySQLdb 执行sql语句时的参数传递方式
2020/03/04 Python
python实现Pyecharts实现动态地图(Map、Geo)
2020/03/25 Python
Python confluent kafka客户端配置kerberos认证流程详解
2020/10/12 Python
Python用户自定义异常的实现
2020/12/25 Python
解决Firefox下不支持outerHTML问题代码分享
2014/06/04 HTML / CSS
HTML5对比HTML4的主要改变和改进总结
2016/05/27 HTML / CSS
Reebok俄罗斯官方网上商店:购买锐步运动服装和鞋子
2016/09/26 全球购物
优秀团支部申报材料
2014/12/26 职场文书
学校教师师德师风承诺书
2015/04/28 职场文书
2015年暑期社会实践方案
2015/07/14 职场文书
2016春季田径运动会广播稿
2015/12/21 职场文书
java设计模式--原型模式详解
2021/07/21 Java/Android
关于CentOS 8 搭建MongoDB4.4分片集群的问题
2021/10/24 MongoDB