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 相关文章推荐
用libTemplate实现静态网页的生成
Oct 09 PHP
兼容PHP5的PHP目录管理函数库
Jul 10 PHP
PHP下打开URL地址的几种方法小结
May 16 PHP
php iconv() : Detected an illegal character in input string
Dec 05 PHP
php中删除字符串中最先出现某个字符的实现代码
Feb 03 PHP
PHP Class&amp;Object -- PHP 自排序二叉树的深入解析
Jun 25 PHP
PHP文件缓存内容保存格式实例分析
Aug 20 PHP
thinkphp实现发送邮件密码找回功能实例
Dec 01 PHP
php编写简单的文章发布程序
Jun 18 PHP
PHP实现XML与数据格式进行转换类实例
Jul 29 PHP
基于yaf框架和uploadify插件,做的一个导入excel文件,查看并保存数据的功能
Jan 24 PHP
使用laravel的Eloquent模型如何获取数据库的指定列
Oct 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
用来解析.htgroup文件的PHP类
2012/09/05 PHP
php实现的ping端口函数实例
2014/11/12 PHP
php.ini中的request_order推荐设置
2015/05/10 PHP
php实现图片上传并利用ImageMagick生成缩略图
2016/03/14 PHP
PHP如何获取当前主机、域名、网址、路径、端口等参数
2017/06/09 PHP
php中钩子(hook)的原理与简单应用demo示例
2019/09/03 PHP
PHP常用字符串函数用法实例总结
2020/06/04 PHP
JS在IE和FF下attachEvent,addEventListener学习笔记
2009/11/26 Javascript
Javascript面向对象扩展库代码分享
2012/03/27 Javascript
JS特殊函数(Function()构造函数、函数直接量)区别介绍
2013/05/19 Javascript
原生JS可拖动弹窗效果实例代码
2013/11/09 Javascript
用html5 js实现点击一个按钮达到浏览器全屏效果
2014/05/28 Javascript
js实现仿Discuz文本框弹出层效果
2015/08/13 Javascript
谈谈AngularJs中的隐藏和显示
2015/12/09 Javascript
JavaScript随机打乱数组顺序之随机洗牌算法
2016/08/02 Javascript
JavaScript之cookie技术详解
2016/11/18 Javascript
Bootstrap基本插件学习笔记之折叠(22)
2016/12/08 Javascript
springMVC + easyui + $.ajaxFileUpload实现文件上传注意事项
2017/04/23 Javascript
jQuery Pagination分页插件_动力节点Java学院整理
2017/07/17 jQuery
浅析JavaScript异步代码优化
2019/03/18 Javascript
基于vue、react实现倒计时效果
2019/08/26 Javascript
vue+iview分页组件的封装
2020/11/17 Vue.js
js实现菜单跳转效果
2020/12/11 Javascript
[59:30]VG vs LGD 2019国际邀请赛淘汰赛 胜者组 BO3 第二场 8.22
2019/09/05 DOTA
Python中正则表达式的用法实例汇总
2014/08/18 Python
python数据批量写入ScrolledText的优化方法
2018/10/11 Python
python模拟菜刀反弹shell绕过限制【推荐】
2019/06/25 Python
解决Django一个表单对应多个按钮的问题
2019/07/18 Python
美国大尺码女装零售商:TORRID
2016/10/01 全球购物
计算机通信专业推荐信
2014/02/22 职场文书
企业管理标语
2014/06/10 职场文书
“九一八事变纪念日”国旗下讲话稿
2014/09/14 职场文书
2014法院四风问题对照检查材料思想汇报
2014/10/04 职场文书
2014年超市员工工作总结
2014/11/18 职场文书
2016年“我们的节日·中秋节”活动总结
2016/04/05 职场文书
HttpClient实现文件上传功能
2022/08/14 Java/Android