php ip归属地数据库下载,IP归属地数据库,附带C,PHP访问代码

最近有打算给博客做个统计插件,看看都是哪儿来的朋友在看我的博客儿,需要一个详细的IP地址归属地数据库。网上找了个纯真的MySQL版的,30多万条数据占了20M左右的数据库空间,觉得有点浪费数据库空间,而且数据库查询时间太慢,特别是要一次性查多个结果时,更是不得了.最主要的是这种应用场合不适合做成数据库形式的。

所以就准备自己做数据库了,自己也有50000亿条数据的数据文件的设计经验。这才30多万条没什么问题。。。按自己的想法生成了文件,并写了PHP和C语言的访问API,心情好的时候再补写上Java啊,汇编啊什么的API也是挺好的。

PHP API(函数):这个是函数形式的PHP代码,博客版面上是写描述,具体代码在这里:ips.php ip_area.php

/**

* IP地址归属地查询 PHP函数版

* @author Hoverlees http://www.hoverlees.com me[at]hoverlees.com

* @comment 此功能同时包含C/C++,PHP类,PHP函数,等版本提供下载。

* 数据库文件及相关代码下载地址:http://www.hoverlees.com/blog/?p=906

*/

/*对象状态常量*/

define('IPV4_AREA_ERROR_SUCCESS',0); //正常

define('IPV4_AREA_ERROR_OPENFILE',-1); //无法打开文件

define('IPV4_AREA_ERROR_FORMAT',-2); //数据库格式不对

/**

* IPv4地址转整数函数,注意本函数不检查IP地址的合法性

* @param $ip IPv4地址

* @return 转换后的整数

*/

function ipv4_atol($ip){}

/**

* 创建IP表对象

* @param $filename 数据库文件名

* @param $index_read_parts 索引划分的块数,如果为1,表示索引全部读入内存(占用大约4M内存空间),如果为2则只需要占用4/2=2M内存临时空间。此值越大,需要的内存缓冲越少,但磁盘的IO次数增加。如果需要循环查询多个IP,建议此值设为1.如果只查询一次可以根据内存要求自行设定。

* @return 用于查询的数据库对象,使用完成后请调用ipv4_area_free释放占用的资源

*/

function ipv4_area_create($filename,$index_read_parts=1){}

/**

* IP址所在地查询

* @param $obj 数据库对象

* @param $ip IP地址,可以为'XXX.XXX.XXX.XXX'格式

* @return 归属地名称

*/

function ipv4_area_search($obj,$ip){}

/**

* 释放IP数据库

* @param $object 由函数ipv4_area_create返回的表对象

*/

function ipv4_area_free($object){}

?>

代码调用示例:

include('./ips.php'); //包含测试数组$test_ips,包含1760个需要查询所在地的IP地址

$s=microtime(true);

$object=ipv4_area_create('./ip_utf8.dat');//初始化数据库

if($object['status']==IPV4_AREA_ERROR_SUCCESS){

foreach($test_ips as $ip){ //循环查询每一个IP的所在地

$area=ipv4_area_search($object,$ip);

echo "IP:{$ip}
AREA:{$area}
\n";

}

}

ipv4_area_free($object); //释放对象

echo microtime(true)-$s; //当创建时参数index_read_parts=1时,查询1760条IP所在地仅需3.68秒(上网本)

?>

PHP IPArea类,功能都跟上面一样的,不过不同的人习惯不一样呗,咱就多提供一种思路了。完整的代码在这里: IPArea.php

/**

* IP地址归属地查询 PHP类版

* @author Hoverlees http://www.hoverlees.com me[at]hoverlees.com

* @comment 此功能同时包含C/C++,PHP类,PHP函数,等版本提供下载。

* 数据库文件及相关代码下载地址:http://www.hoverlees.com/blog/?p=906

*/

class IPArea{

/*对象状态常量*/

const IPV4_AREA_ERROR_SUCCESS=0;//正常

const IPV4_AREA_ERROR_OPENFILE=-1; //无法打开文件

const IPV4_AREA_ERROR_FORMAT=-2; //数据库格式不对

private $innerObject;

/**

* 构造函数

* @param $filename 数据库文件名

* @param $index_read_parts 索引划分的块数,如果为1,表示索引全部读入内存(占用大约4M内存空间),如果为2则只需要占用4/2=2M内存临时空间。此值越大,需要的内存缓冲越少,但磁盘的IO次数增加。如果需要循环查询多个IP,建议此值设为1.如果只查询一次可以根据内存要求自行设定。

*/

public function IPArea($filename,$index_read_parts=1){}

/**

* 取得对象状态

* @return 返回状态常量之一

*/

public function getStatus(){}

/**

* 取得数据库的编码

* @return 返回编码,可能是UTF-8或GBK

*/

public function getDBEncoding(){}

/**

* IP址所在地查询

* @param $ip IP地址,可以为'XXX.XXX.XXX.XXX'格式

* @return 归属地名称

*/

public function search($ip){}

/**

* 释放对象占用的资源

*/

public function release(){

}

/**

* IPv4地址转整数函数,注意本函数不检查IP地址的合法性

* @param $ip IPv4地址

* @return 转换后的整数

*/

public static function atol($ip){}

private function getAreaString($section_offset){}

}

?>

调用示例代码:

include('./ips.php'); //包含测试数组$test_ips,包含1760个需要查询所在地的IP地址

$ia=new IPArea('./ip_utf8.dat');

if($ia->getStatus()==0){

foreach($test_ips as $ip){ //循环查询每一个IP的所在地

$area=$ia->search($ip);

echo "IP:{$ip}
AREA:{$area}
\n";

}

}

$ia->release();

?>

接下来是大家期待的C语言代码了,C语言查询1760个IP地址归属地仅需要0.6s。

ip_area.h ip_area.c ips.h

/**

* IP地址归属地查询 C/C++版

* @author Hoverlees http://www.hoverlees.com me[at]hoverlees.com

* @comment 此功能同时包含C/C++,PHP类,PHP函数,等版本提供下载。

* 数据库文件及相关代码下载地址:http://www.hoverlees.com/blog/?p=906

*/

#include

#include

#include

#ifndef __HOVERLEES_IP_AREA_H

#define __HOVERLEES_IP_AREA_H

/*对象状态常量*/

#define IPV4_AREA_ERROR_SUCCESS 0 //正常

#define IPV4_AREA_ERROR_OPENFILE -1 //无法打开文件

#define IPV4_AREA_ERROR_FORMAT -2 //数据库格式不对

typedef struct _IP_AREA_OBJ{

int status;

int num_items;

int index_pos;

int data_pos;

int index_read_parts;

int each_read_item;

int each_read_byte;

FILE* fp;

char* last_data;

char encoding[8];

}IP_AREA_OBJ;

/**

* IPv4地址转整数函数,注意本函数不检查IP地址的合法性

* @param ip IPv4地址

* @return 转换后的32位整数

*/

unsigned int ipv4_atoi(const char* ip);

/**

* 创建IP表对象

* @param filename 数据库文件名

* @param index_read_parts 索引划分的块数,如果为1,表示索引全部读入内存(占用大约4M内存空间),如果为2则只需要占用4/2=2M内存临时空间。此值越大,需要的内存缓冲越少,但磁盘的IO次数增加。如果需要循环查询多个IP,建议此值设为1.如果只查询一次可以根据内存要求自行设定。

* @return 用于查询的数据库对象,使用完成后请调用ipv4_area_free释放占用的资源

*/

IP_AREA_OBJ* ipv4_area_create(const char* filename,int index_read_parts);

/**

* 释放IP数据库

* @param obj 由函数ipv4_area_create返回的表对象

*/

void ipv4_area_free(IP_AREA_OBJ* obj);

/**

* IP址所在地查询

* @param obj 数据库对象

* @param ip IP地址,可以为'XXX.XXX.XXX.XXX'格式

* @param buf 地址缓存,请确保大于100字节。

* @return buf本身

*/

char* ipv4_area_search(IP_AREA_OBJ* obj,const char* ip,char* buf);

#endif

C语言调用示例:

#include

#include

#include "ip_area.h"

#include "ips.h" //1760多个IP地址数组

void main(int argc,char* argv[]){

int i;

char out[100];

IP_AREA_OBJ* obj;

obj=ipv4_area_create("./ip_utf8.dat",1);

for(i=0;i<1767;i++){

ipv4_area_search(obj,ips[i],out);

printf("IP:%s AREA:%s\n",ips[i],out);

}

ipv4_area_free(obj);

}

有空的时候再传传JAVA的版本上来。如果代码有错误,请指出,我会尽快fix掉。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值