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 相关文章推荐
phpMyadmin 用户权限中英对照
Apr 02 PHP
php去掉字符串的最后一个字符附substr()的用法
Mar 23 PHP
PHPWind与Discuz截取字符函数substrs与cutstr性能比较
Dec 05 PHP
PHP连接SQLSERVER 注意事项(附dll文件下载)
Jun 28 PHP
php给一组指定关键词添加span标签的方法
Mar 31 PHP
php两种无限分类方法实例
Apr 21 PHP
PHP实现的迷你漂流瓶
Jul 29 PHP
PHP上传图片类显示缩略图功能
Jun 30 PHP
利用PHP判断文件是否为图片的方法总结
Jan 06 PHP
PHP封装的验证码工具类定义与用法示例
Aug 22 PHP
PHP配置文件php.ini中打开错误报告的设置方法
Jan 09 PHP
用php如何解决大文件分片上传问题
Jul 07 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遍历二维数组的代码
2011/04/22 PHP
discuz免激活同步登入代码修改方法(discuz同步登录)
2013/12/24 PHP
php生成word并下载代码实例
2019/03/15 PHP
jsonp原理及使用
2013/10/28 Javascript
Mac OS X 系统下安装和部署Egret引擎开发环境
2014/09/03 Javascript
javascript中定义类的方法详解
2015/02/10 Javascript
Windows系统下使用Sublime搭建nodejs环境
2015/04/13 NodeJs
form表单转Json提交的方法(推荐)
2016/09/23 Javascript
原生JS实现的放大镜效果实例代码
2016/10/15 Javascript
Javascript基于jQuery UI实现选中区域拖拽效果
2016/11/25 Javascript
Vue-router结合transition实现app前进后退动画切换效果的实例
2017/10/11 Javascript
详解vue 计算属性与方法跟侦听器区别(面试考点)
2018/04/23 Javascript
vue实现弹框遮罩点击其他区域弹框关闭及v-if与v-show的区别介绍
2018/09/29 Javascript
js比较两个单独的数组或对象是否相等的实例代码
2019/04/28 Javascript
vue中利用simplemde实现markdown编辑器(增加图片上传功能)
2019/04/29 Javascript
javascript设计模式之迭代器模式
2020/01/30 Javascript
Vue实现input宽度随文字长度自适应操作
2020/07/29 Javascript
javascript实现随机抽奖功能
2020/12/30 Javascript
Python的“二维”字典 (two-dimension dictionary)定义与实现方法
2016/04/27 Python
python简单读取大文件的方法
2016/07/01 Python
python hashlib加密实现代码
2019/10/17 Python
CSS3实现时间轴特效
2020/11/02 HTML / CSS
html5仿支付宝密码框的实现代码
2017/09/06 HTML / CSS
opencv实现图像几何变换
2021/03/24 Python
咖啡蛋糕店创业计划书
2014/01/28 职场文书
青蓝工程实施方案
2014/03/27 职场文书
最新离婚协议书范本
2014/08/19 职场文书
班子四风对照检查材料
2014/08/21 职场文书
基层党员群众路线教育实践活动个人对照检查材料思想汇报
2014/10/05 职场文书
投标邀请书范本
2015/02/02 职场文书
2015年机械设备管理工作总结
2015/05/04 职场文书
教师节表彰会主持词
2015/07/06 职场文书
2016年庆“七一”主题党日活动总结
2016/04/05 职场文书
python学习之panda数据分析核心支持库
2021/05/07 Python
为什么在foreach循环中JAVA集合不能添加或删除元素
2021/06/11 Java/Android
kubernetes集群搭建Zabbix监控平台的详细过程
2022/07/07 Servers