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 相关文章推荐
将RTF格式的文件转成HTML并在网页中显示的代码
Oct 09 PHP
php Smarty date_format [格式化时间日期]
Mar 15 PHP
php下目前为目最全的CURL中文说明
Aug 01 PHP
PHP中数组合并的两种方法及区别介绍
Sep 14 PHP
探讨Smarty中如何获取数组的长度以及smarty调用php函数的详解
Jun 20 PHP
PHP中array_map与array_column之间的关系分析
Aug 19 PHP
完整删除ecshop中获取店铺信息的API
Dec 24 PHP
php求一个网段开始与结束IP地址的方法
Jul 09 PHP
php实现获取农历(阴历)、节日、节气的类与用法示例
Nov 20 PHP
Thinkphp5行为使用方法汇总
Dec 21 PHP
php 读写json文件及修改json的方法
Mar 07 PHP
使用PHPWord生成word文档的方法详解
Jun 06 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脚本的10个技巧(4)
2006/10/09 PHP
用PHP实现图象锐化代码
2007/06/14 PHP
php Smarty 字符比较代码
2011/02/27 PHP
JQuery 实现的页面滚动时浮动窗口控件
2009/07/10 Javascript
js和jquery批量绑定事件传参数一(新猪猪原创)
2010/06/23 Javascript
jquery 中的each()跳出循环的语句
2014/05/23 Javascript
JavaScript实现添加、查找、删除元素
2015/07/02 Javascript
JS+DIV+CSS排版布局实现美观的选项卡效果
2015/10/10 Javascript
jquery实现全选和全不选功能效果的实现代码【推荐】
2016/05/05 Javascript
js中最容易被忽视的事件问题大总结
2016/05/15 Javascript
走进AngularJs之过滤器(filter)详解
2017/02/17 Javascript
Angular中ng-repeat与ul li的多层嵌套重复问题
2017/07/24 Javascript
基于Vue实现后台系统权限控制的示例代码
2017/08/29 Javascript
node基于puppeteer模拟登录抓取页面的实现
2018/05/09 Javascript
使用Angular 6创建各种动画效果的方法
2018/10/10 Javascript
JS实现根据详细地址获取经纬度功能示例
2019/04/16 Javascript
IE11下CKEditor在Bootstrap Modal中下拉问题的解决
2019/09/25 Javascript
Vue3.0中的monorepo管理模式的实现
2019/10/14 Javascript
vue自定义switch开关组件,实现样式可自行更改
2019/11/01 Javascript
JavaScript中Object、map、weakmap的区别分析
2020/12/15 Javascript
[47:50]Secret vs VP 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
python实现获取客户机上指定文件并传输到服务器的方法
2015/03/16 Python
pandas中Timestamp类用法详解
2017/12/11 Python
Django+Ajax+jQuery实现网页动态更新的实例
2018/05/28 Python
Python实现删除排序数组中重复项的两种方法示例
2019/01/31 Python
Python request操作步骤及代码实例
2020/04/13 Python
机械专业应届毕业生自荐书
2014/06/12 职场文书
社区个人对照检查材料(群众路线)
2014/09/26 职场文书
党性分析自查总结
2014/10/14 职场文书
小学科学教学计划
2015/01/21 职场文书
2015年清明节扫墓演讲稿
2015/03/18 职场文书
上班迟到检讨书范文
2015/05/06 职场文书
实施意见格式范本
2015/06/05 职场文书
圣诞晚会主持词
2015/07/01 职场文书
2016教师党员学习心得体会
2016/01/21 职场文书
找规律教学反思
2016/02/23 职场文书