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 相关文章推荐
对javascript和select部件的结合运用
Oct 09 PHP
php SQL Injection with MySQL
Feb 27 PHP
php设计模式  Command(命令模式)
Jun 17 PHP
IIS6.0中配置php服务全过程解析
Aug 07 PHP
浅析ThinkPHP的模板输出功能
Jul 01 PHP
php实现的css文件背景图片下载器代码
Nov 11 PHP
php检索或者复制远程文件的方法
Mar 13 PHP
thinkPHP基于ajax实现的菜单与分页示例
Jul 12 PHP
PHP魔术方法之__call与__callStatic使用方法
Jul 23 PHP
laravel 数据验证规则详解
Oct 23 PHP
php使用自带dom扩展进行元素匹配的原理解析
May 29 PHP
PHP获取当前时间不准确问题解决方案
Aug 14 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作的文本留言本的例子(六)
2006/10/09 PHP
php中使用parse_url()对网址进行解析的实现代码(parse_url详解)
2012/01/03 PHP
php写的带缓存数据功能的mysqli类
2012/09/06 PHP
js星星评分效果
2014/07/24 Javascript
js交换排序 冒泡排序算法(Javascript版)
2014/10/04 Javascript
AngularJs实现ng1.3+表单验证
2015/12/10 Javascript
深入浅析Vue组件开发
2016/11/25 Javascript
深入学习Bootstrap表单
2016/12/13 Javascript
js学习总结之DOM2兼容处理重复问题的解决方法
2017/07/27 Javascript
Nodejs 和Session 原理及实战技巧小结
2017/08/25 NodeJs
基于Vue的移动端图片裁剪组件功能
2017/11/28 Javascript
解决 viewer.js 动态更新图片导致无法预览的问题
2019/05/14 Javascript
浅谈Express.js解析Post数据类型的正确姿势
2019/05/30 Javascript
浅谈Vuex的this.$store.commit和在Vue项目中引用公共方法
2020/07/24 Javascript
跟老齐学Python之赋值,简单也不简单
2014/09/24 Python
python fabric使用笔记
2015/05/09 Python
Python的Django框架中URLconf相关的一些技巧整理
2015/07/18 Python
浅谈flask源码之请求过程
2018/07/26 Python
解决python selenium3启动不了firefox的问题
2018/10/13 Python
python打印9宫格、25宫格等奇数格 满足横竖斜相加和相等
2019/07/19 Python
Python class的继承方法代码实例
2020/02/14 Python
Python实现爬取网页中动态加载的数据
2020/08/17 Python
Numpy(Pandas)删除全为零的列的方法
2020/09/11 Python
python Pexpect模块的使用
2020/12/25 Python
Python接口自动化系列之unittest结合ddt的使用教程详解
2021/02/23 Python
在什么时候需要使用"常引用"
2015/12/31 面试题
车间组长岗位职责
2013/12/20 职场文书
乡镇信息公开实施方案
2014/03/23 职场文书
感恩节活动策划方案
2014/05/16 职场文书
父亲节活动策划方案
2014/08/24 职场文书
学雷锋倡议书
2015/01/19 职场文书
初中运动会前导词
2015/07/20 职场文书
装修公司管理制度
2015/08/05 职场文书
详解Python描述符的工作原理
2021/06/11 Python
MySQL创建表操作命令分享
2022/03/25 MySQL
Android Gradle 插件自定义Plugin实现注意事项
2022/06/16 Java/Android