您的位置:首页 > 编程语言 > PHP开发

php查询IP地理位置(dat数据库)

2016-10-21 18:07 423 查看
ipdata类源码

<?php

define('__QQWRY__', dirname(__FILE__) . "/qqwry.dat");
class ipdata {
var $StartIP = 0;
var $EndIP = 0;
var $Country = '';
var $Local = '';

var $CountryFlag = 0; // 标识 Country位置
// 0x01,随后3字节为Country偏移,没有Local
// 0x02,随后3字节为Country偏移,接着是Local
// 其他,Country,Local,Local有类似的压缩。可能多重引用。

var $fp;

var $FirstStartIp = 0;
var $LastStartIp = 0;
var $EndIpOff = 0;

function getStartIp($RecNo) {
$offset = $this->FirstStartIp + $RecNo * 7;
@fseek($this->fp, $offset, SEEK_SET);
$buf = fread($this->fp, 7);
$this->EndIpOff = ord($buf[4]) + (ord($buf[5]) * 256) + (ord($buf[6]) * 256 * 256);
$this->StartIp = ord($buf[0]) + (ord($buf[1]) * 256) + (ord($buf[2]) * 256 * 256) + (ord($buf[3]) * 256 * 256 * 256);
return $this->StartIp;
}

function getEndIp() {
@fseek($this->fp, $this->EndIpOff, SEEK_SET);
$buf = fread($this->fp, 5);
$this->EndIp = ord($buf[0]) + (ord($buf[1]) * 256) + (ord($buf[2]) * 256 * 256) + (ord($buf[3]) * 256 * 256 * 256);
$this->CountryFlag = ord($buf[4]);
return $this->EndIp;
}

function getCountry() {
switch ($this->CountryFlag) {
case 1:
case 2:
$this->Country = $this->getFlagStr($this->EndIpOff + 4);
$this->Local = (1 == $this->CountryFlag) ? '' : $this->getFlagStr($this->EndIpOff + 8);
break;
default:
$this->Country = $this->getFlagStr($this->EndIpOff + 4);
$this->Local = $this->getFlagStr(ftell($this->fp));
}
}

function getFlagStr($offset) {
$flag = 0;

while (1) {
@fseek($this->fp, $offset, SEEK_SET);
$flag = ord(fgetc($this->fp));

if ($flag == 1 || $flag == 2) {
$buf = fread($this->fp, 3);

if ($flag == 2) {
$this->CountryFlag = 2;
$this->EndIpOff = $offset - 4;
}

$offset = ord($buf[0]) + (ord($buf[1]) * 256) + (ord($buf[2]) * 256 * 256);
} else {
break;
}

}

if ($offset < 12) {
return '';
}

@fseek($this->fp, $offset, SEEK_SET);

return $this->getStr();
}

function getStr() {
$str = '';

while (1) {
$c = fgetc($this->fp);

if (ord($c[0]) == 0) {
break;
}

$str .= $c;
}

return iconv('gbk', 'utf-8', $str);
}

function geop($dotip = '') {
if (!$dotip) {
return;
}

if (preg_match("/^(127)/", $dotip)) {
$this->Country = '本地网络';
return;
} else if (preg_match("/^(192)/", $dotip)) {
$this->Country = '局域网';
return;
}

$nRet;
$ip = $this->IpToInt($dotip);
$this->fp = fopen(__QQWRY__, "rb");

if ($this->fp == NULL) {
$szLocal = "OpenFileError";
return 1;
}

@fseek($this->fp, 0, SEEK_SET);
$buf = fread($this->fp, 8);
$this->FirstStartIp = ord($buf[0]) + (ord($buf[1]) * 256) + (ord($buf[2]) * 256 * 256) + (ord($buf[3]) * 256 * 256 * 256);
$this->LastStartIp = ord($buf[4]) + (ord($buf[5]) * 256) + (ord($buf[6]) * 256 * 256) + (ord($buf[7]) * 256 * 256 * 256);

$RecordCount = floor(($this->LastStartIp - $this->FirstStartIp) / 7);

if ($RecordCount <= 1) {
$this->Country = "FileDataError";
fclose($this->fp);
return 2;
}

$RangB = 0;
$RangE = $RecordCount;

// Match ...
while ($RangB < $RangE - 1) {
$RecNo = floor(($RangB + $RangE) / 2);
$this->getStartIp($RecNo);

if ($ip == $this->StartIp) {
$RangB = $RecNo;
break;
}

if ($ip > $this->StartIp) {
$RangB = $RecNo;
} else {
$RangE = $RecNo;
}

}

$this->getStartIp($RangB);
$this->getEndIp();

if (($this->StartIp <= $ip) && ($this->EndIp >= $ip)) {
$this->getCountry();
} else {
$this->Country = '未知';
$this->Local = '';
}

fclose($this->fp);
}

function IpToInt($Ip) {
$array = explode('.', $Ip);
$Int = ($array[0] * 256 * 256 * 256) + ($array[1] * 256 * 256) + ($array[2] * 256) + $array[3];

return $Int;
}
}


使用

<?php

require "./util/ipdata/ipdata.class.php";

$ip = '220.177.9.69';
$ipdata = new ipdata();
$ipdata->geop($ip);
echo $ipdata->Country.$ipdata->Local;


运行结果



文/hopevow(简书作者)

原文链接:http://www.jianshu.com/p/b7709779e210

著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: