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 MsSql server时遇到的中文编码问题
Jun 11 PHP
php判断输入不超过mysql的varchar字段的长度范围
Jun 24 PHP
解析PHP可变函数的经典用法
Jun 20 PHP
php中使用array_filter()函数过滤空数组的实现代码
Aug 19 PHP
PHP实现的简单mock json脚本分享
Feb 10 PHP
php解析xml方法实例详解
May 12 PHP
typecho插件编写教程(二):写一个新插件
May 28 PHP
ThinkPHP使用Ueditor的方法详解
May 20 PHP
PHP数组编码gbk与utf8互相转换的两种方法
Sep 01 PHP
thinkPHP模板中函数的使用方法示例
Nov 30 PHP
php设计模式之工厂模式用法经典实例分析
Sep 20 PHP
Laravel 读取 config 下的数据方法
Oct 13 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
超神学院:鹤熙已踏入神圣领域,实力不比凯莎弱
2020/03/02 国漫
php绘制一个扇形的方法
2015/01/24 PHP
asp.net和php的区别点总结
2019/10/10 PHP
javascript cookies操作集合
2010/04/12 Javascript
更优雅的事件触发兼容
2011/10/24 Javascript
javascript计算用户打开网页的停留时间
2014/01/09 Javascript
使用jquery prev()方法找到同级的前一个元素
2014/07/11 Javascript
基于WebUploader的文件上传js插件
2016/08/19 Javascript
JS模拟实现ECMAScript5新增的数组方法
2017/03/20 Javascript
使用vue-cli+webpack搭建vue开发环境的方法
2017/12/22 Javascript
nodejs同步调用获取mysql数据时遇到的大坑
2019/03/02 NodeJs
vue 项目 iOS WKWebView 加载
2019/04/17 Javascript
使用Vue Composition API写出清晰、可扩展的表单实现
2020/06/10 Javascript
python解析模块(ConfigParser)使用方法
2013/12/10 Python
Python3实现抓取javascript动态生成的html网页功能示例
2017/08/22 Python
python 实现对文件夹中的图像连续重命名方法
2018/10/25 Python
Python3环境安装Scrapy爬虫框架过程及常见错误
2019/07/12 Python
python3中numpy函数tile的用法详解
2019/12/04 Python
python读取ini配置文件过程示范
2019/12/23 Python
python 图像插值 最近邻、双线性、双三次实例
2020/07/05 Python
Python三维绘图之Matplotlib库的使用方法
2020/09/20 Python
canvas简易绘图的实现(海绵宝宝篇)
2018/07/04 HTML / CSS
navabi英国:设计师大码女装
2019/06/25 全球购物
荷兰在线钓鱼商店:Raven
2019/06/26 全球购物
Java中的异常处理机制的简单原理和应用
2013/04/27 面试题
公司年会演讲稿范文
2014/01/11 职场文书
协议书怎么写
2014/04/21 职场文书
土地转让协议书
2014/09/27 职场文书
2014年领导班子工作总结
2014/12/11 职场文书
堂吉诃德读书笔记
2015/06/30 职场文书
消费者投诉书范文
2015/07/02 职场文书
nginx简单配置多个server的方法
2021/03/31 Servers
CSS3 制作精美的定价表
2021/04/06 HTML / CSS
Python开发五子棋小游戏
2022/05/02 Python
MySQL事务的隔离级别详情
2022/07/15 MySQL
Python 第三方库 openpyxl 的安装过程
2022/12/24 Python