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 相关文章推荐
PHP5在Apache下的两种模式的安装
Sep 05 PHP
一个简单的PHP投票程序源码
Mar 11 PHP
不要轻信 PHP_SELF的安全问题
Sep 05 PHP
DEDE采集大师官方留后门的删除办法
Jan 08 PHP
php设计模式 Interpreter(解释器模式)
Jun 26 PHP
PHP设计模式 注册表模式(多个类的注册)
Feb 05 PHP
将二维数组转为一维数组的2种方法
May 26 PHP
PHP对文件进行加锁、解锁实例
Jan 23 PHP
php curl模拟post请求和提交多维数组的示例代码
Nov 19 PHP
Zend Framework入门教程之Zend_Mail用法示例
Dec 08 PHP
PHP解耦的三重境界(浅谈服务容器)
Mar 13 PHP
可兼容php5与php7的cURL文件上传功能实例分析
May 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代码
2007/03/03 PHP
PHP文件上传主要代码讲解
2013/09/30 PHP
javascript对象的property和prototype是这样一种关系
2007/03/24 Javascript
JavaScript的Cookies
2008/01/16 Javascript
javascript 语法基础 想学习js的朋友可以看看
2009/12/16 Javascript
jquery操作cookie插件分享
2014/01/14 Javascript
JavaScript遍历table表格中的某行某列并打印其值
2014/07/08 Javascript
js拼接html注意问题示例探讨
2014/07/14 Javascript
javascript使用for循环批量注册的事件不能正确获取索引值的解决方法
2014/12/20 Javascript
分享纯手写漂亮的表单验证
2015/11/19 Javascript
JavaScript数组操作详解
2017/02/04 Javascript
JS中利用localStorage防止页面动态添加数据刷新后数据丢失
2017/03/10 Javascript
基于jQuery实现的Ajax 验证用户名唯一性实例代码
2017/06/28 jQuery
vue增删改查的简单操作
2017/07/15 Javascript
js实现图片放大展示效果
2017/08/30 Javascript
layui的table单击行勾选checkbox功能方法
2018/08/14 Javascript
axios使用拦截器统一处理所有的http请求的方法
2018/11/02 Javascript
小程序点击图片实现自动播放视频
2020/05/29 Javascript
Vue加载json文件的方法简单示例
2019/01/28 Javascript
微信小程序前端自定义分享的实现方法
2019/06/13 Javascript
微信小程序实现购物车小功能
2020/12/30 Javascript
在Django中限制已登录用户的访问的方法
2015/07/23 Python
python 查找文件名包含指定字符串的方法
2018/06/05 Python
解决Python中pandas读取*.csv文件出现编码问题
2019/07/12 Python
使用Fabric自动化部署Django项目的实现
2019/09/27 Python
如何使用python3获取当前路径及os.path.dirname的使用
2019/12/13 Python
使用Python打造一款间谍程序的流程分析
2020/02/21 Python
Html5 video标签视频的最佳实践
2020/02/26 HTML / CSS
美国领先的宠物用品和宠物食品零售商:Petco
2020/10/28 全球购物
大学自荐信
2013/12/12 职场文书
大学生通用个人的自我评价
2014/02/10 职场文书
《月亮湾》教学反思
2014/04/14 职场文书
介绍长城的导游词
2015/01/30 职场文书
Python Django搭建文件下载服务器的实现
2021/05/10 Python
分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了
2021/05/21 Redis
win11无法登录onedrive错误代码0x8004def7怎么办 ?
2022/04/05 数码科技