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 相关文章推荐
加强版phplib的DB类
Mar 31 PHP
php 智能404跳转代码,适合换域名没改变目录的网站
Jun 04 PHP
解析PHP中常见的mongodb查询操作
Jun 20 PHP
微信扫描二维码登录网站代码示例
Dec 30 PHP
ThinkPHP分页类使用详解
Mar 05 PHP
纯PHP生成的一个树叶图片画图例子
Apr 16 PHP
Codeigniter生成Excel文档的简单方法
Jun 12 PHP
php基于str_pad实现卡号不足位数自动补0的方法
Nov 12 PHP
Laravel 5.4向IoC容器中添加自定义类的方法示例
Aug 15 PHP
PHP文件系统管理(实例讲解)
Sep 19 PHP
PHP利用缓存处理用户注册时的邮箱验证,成功后用户数据存入数据库操作示例
Dec 31 PHP
通过实例解析PHP数据类型转换方法
Jul 11 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中生成随机密码的自定义函数代码
2013/10/21 PHP
jQuery+Ajax+PHP“喜欢”评级功能实现代码
2015/10/08 PHP
PHP实践教程之过滤、验证、转义与密码详解
2017/07/24 PHP
php中钩子(hook)的原理与简单应用demo示例
2019/09/03 PHP
php使用自带dom扩展进行元素匹配的原理解析
2020/05/29 PHP
node.js中的events.emitter.once方法使用说明
2014/12/10 Javascript
javascript验证邮件地址和MX记录的方法
2015/06/16 Javascript
深入理解JavaScript 函数
2016/06/06 Javascript
关于Node.js中Buffer的一些你可能不知道的用法
2017/03/28 Javascript
NodeJs通过async/await处理异步的方法
2017/10/09 NodeJs
React Native中导航组件react-navigation跨tab路由处理详解
2017/10/31 Javascript
解析Angular 2+ 样式绑定方式
2018/01/15 Javascript
JavaScript中arguments和this对象用法分析
2018/08/08 Javascript
详解vue项目打包步骤
2019/03/29 Javascript
[02:45]DOTA2英雄敌法师基础教程
2013/11/25 DOTA
实例解析Python的Twisted框架中Deferred对象的用法
2016/05/25 Python
django传值给模板, 再用JS接收并进行操作的实例
2018/05/28 Python
利用pandas进行大文件计数处理的方法
2018/07/25 Python
django进阶之cookie和session的使用示例
2018/08/17 Python
Python 私有化操作实例分析
2019/11/21 Python
pytorch实现建立自己的数据集(以mnist为例)
2020/01/18 Python
使用canvas来完成线性渐变和径向渐变的功能的方法示例
2019/07/25 HTML / CSS
naturalizer加拿大官网:美国娜然女鞋
2017/04/04 全球购物
施华洛世奇意大利官网:SWAROVSKI意大利
2018/07/23 全球购物
您在慕尼黑的跑步商店:Lauf-bar
2019/10/11 全球购物
运输服务质量承诺书
2014/03/27 职场文书
本科毕业生应聘自荐信范文
2014/06/26 职场文书
副主任竞聘演讲稿
2014/08/18 职场文书
大学生毕业个人总结
2015/02/15 职场文书
老公保证书怎么写
2015/02/26 职场文书
讲座通知范文
2015/04/23 职场文书
南京南京观后感
2015/06/02 职场文书
2016年十一促销广告语
2016/01/28 职场文书
《爬天都峰》教学反思
2016/02/23 职场文书
2016年小学“感恩教师”主题队日活动总结
2016/04/01 职场文书
Go timer如何调度
2021/06/09 Golang