php 通过 IPIP.NET 数据库来查询IP地址信息
本文章采用的是 ipip 所提供的
IPIP 今后将不再提供
打包下载,包含源码
使用方法:
将
17monipdb.datx
(20190109) 文件来查询IP信息,代码来自官方github,我仅做简化与小幅优化!IPIP 今后将不再提供
.datx
格式的数据库,因此下面的代码今后肯定会过时,如果您需要下载datx数据库,可以点击下方的链接来下载博主为您分流的文件。打包下载,包含源码
使用方法:
将
17monipdb.datx
文件放到主目录的/data/
目录下,再新建一个ipip.php
文件,复制下面的代码:<?php
class ipip
{
private $file;
private $offset;
private $index;
public function __construct($path=null)
{
if(empty($path)) $path = $_SERVER['DOCUMENT_ROOT'] . "/data/17monipdb.datx";
if (!is_file($path))
throw new \Exception("{$path} is not exits.");
$this->file = fopen($path, 'rb');
if (!is_resource($this->file))
throw new \Exception("{$path} fopen failed.");
$this->offset = unpack('Nlen', fread($this->file, 4));
$this->index = fread($this->file, $this->offset['len'] - 4);
}
public function find($ip)
{
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === FALSE)
return FALSE; // or throw Exception?
$nip2 = pack('N', ip2long($ip));
$ips = explode('.', $ip);
$idx = (256 * $ips[0] + $ips[1]) * 4;
$start = unpack('Vlen', substr($this->index, $idx, 4));
$off = NULL;
$len = NULL;
$max = $this->offset['len'] - 262144 - 4;
for ($start = $start['len'] * 9 + 262144; $start < $max; $start += 9) {
$tmp = $this->index[$start] . $this->index[$start + 1] . $this->index[$start + 2] . $this->index[$start + 3];
if ($tmp >= $nip2) {
$off = unpack('Vlen', substr($this->index, $start + 4, 3) . "\x0");
$len = unpack('nlen', $this->index[$start + 7] . $this->index[$start + 8]);
break;
}
}
if ($off === NULL) return FALSE;
fseek($this->file, $this->offset['len'] + $off['len'] - 262144);
return explode("\t", fread($this->file, $len['len']));
}
// 不擅长php的我只能写出这种蠢代码了 XD
public function info($ip) {
$info = $this->find($ip);
if (empty($info)) {
return "火星";
} else {
return implode('', array_unique($info));
}
}
}
之后新建一个 .htaccess
,禁止此目录被访问:order allow,deny
deny from all
调用方法如下:<?php
require_once $_SERVER['DOCUMENT_ROOT'] . '/data/ipip.php';
$bs = new ipip();
$ip = $_SERVER["REMOTE_ADDR"];
?>
你丫的IP是 <?php echo $ip; ?>,来自于 <?php echo $bs->info($ip) ?>
测试地址本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。