php获取客户端真实ip地址,
准备工作:
建议一个本地IP地址数据库。请从http://www.cz88.net/.的这个网站下载一个纯IP数据库,安装完成后,从安装目录中取出QQWry.dat文件。这是我们要的IP数据库,放在你要的目录下。
本前端IP地址查询处理类
?服务器端编程语言(Professional Hypertext Preprocessor的缩写)
* IP地理位置查询类
类助手_ IpLocation
/**
* QQWry。Dat文件指针
* @var资源
private $ fp
/**
*第一个IP记录的偏移地址
* @var int
private $ firstip
/**
*最后一个IP记录的偏移地址
* @var int
private $ lastip
/**
* IP记录总数(不包括版本信息记录)
* @var int
私人$ totalip
/**
*构造函数,打开QQWry。Dat文件并初始化类中的信息
* @ param string文件名
public function _ _ construct($ filename= qqwry . dat )
$ this-FP=0;
if (($this- fp=fopen($filename, rb ))!==假){
$ this-first IP=$ this-getlong();
$ this-lastip=$ this-getlong();
$ this-totalip=($ this-lastip-$ this-first IP)/7;
//注册析构函数,以便它可以在程序执行结束时执行。
寄存器_关闭_功能(数组(
$这个,
_ _毁灭
));
/**
*析构函数,用于在页面执行后自动关闭打开的文件。
公共函数__destruct()
if(this-FP){
fclose(这-
$ this-FP=0;
/**
*返回读取的长整数。
* @访问私有
* @return int
私有函数getlong()
//将读取的4字节little-endian编码转换成长整数。
$result=unpack(Vlong ,fread($this- fp,4));
返回$ result[ long ];
/**
*返回读取的3字节长整数。
* @访问私有
* @return int
私有函数getlong3()
//将读取的小端编码的3个字节转换为长整数
$result=unpack(Vlong ,fread($this- fp,3)。chr(0));
返回$ result[ long ];
/**
*返回可以比较的压缩IP地址。
* @访问私有
* @param string $ip
* @返回字符串
专用功能包(ip)
//将IP地址转换为长整数,如果PHP5中IP地址错误则返回False,
//此时intval将Flase转换成integer -1,然后压缩成big-endian编码的字符串。
return pack(N ,intval(IP 2 long($ IP)));
/**
*返回读取的字符串。
* @访问私有
* @param string $data
* @返回字符串
私有函数getstring($data= )
$char=fread($this- fp,1);
While (ord($char) 0) {//字符串以C格式保存到结尾
$data。=$ char//在给定字符串后连接读取的字符
$char=fread($this- fp,1);
返回iconv(gbk , utf-8 ,$ data);
/**
*返回地区信息
* @访问私有
* @返回字符串
私有函数getarea()
$byte=fread($this- fp,1);//标志字节
switch(order($ byte)){
0://如果没有区域信息
$ area=“”;
打破;
案例1:
2://标志字节为1或2,表示区域信息被重定向。
fseek($this- fp,$ this-getlong 3());
$ area=$ this-getstring();
打破;
Default: //否则,表示区域信息没有被重定向。
$ area=$ this-getstring($ byte);
打破;
return $ area
/**
*根据给定的IP地址或域名,返回该地区的信息。
* @访问公共
* @param string $ip
* @返回数组
公共函数getlocation($ip)
如果(!$this- fp)
返回null//如果数据文件没有正确打开,直接返回null
$ location[ IP ]=gethostbyname($ IP);//将输入的域名转换成IP地址
$ IP=$ this-pack IP($ location[ IP ]);//将输入的IP地址转换成可比较的IP地址
//非法IP地址将被转换为255.255.255.255
//分割搜索
$ l=0;//搜索的下限
$ u=$ this-totalip;//搜索的上限
$ findip=$ this-lastip;//如果没有找到,返回最后一条IP记录(QQWry的版本信息。Dat)
While ($l=$u) {//当上边界小于下边界时,查找失败。
$i=下限(($ l $ u)/2);//计算近似的中间记录
fseek($this- fp,$ this-first IP $ I * 7);
$beginip=strrev(fread($this- fp,4));//获取中间记录的开始互联网协议(互联网协议)地址
//strrev函数在这里的作用是将小端的的压缩互联网协议(互联网协议)地址转化为大端的的格式
//以便用于比较,后面相同。
if ($ip $beginip) { //用户的互联网协议(互联网协议)小于中间记录的开始互联网协议(互联网协议)地址时
$ u=$ I-1;//将搜索的上边界修改为中间记录减一
}否则{
fseek($this- fp,$ this-getlong 3());
$endip=strrev(fread($this- fp,4));//获取中间记录的结束互联网协议(互联网协议)地址
if ($ip $endip) { //用户的互联网协议(互联网协议)大于中间记录的结束互联网协议(互联网协议)地址时
$ l=$ I 1;//将搜索的下边界修改为中间记录加一
} else { //用户的互联网协议(互联网协议)在中间记录的互联网协议(互联网协议)范围内时
$ findip=$ this-first IP $ I * 7;
打破;//则表示找到结果,退出循环
//获取查找到的互联网协议(互联网协议)地理位置信息
fseek($this- fp,$ findip);
$ location[ begin IP ]=long 2 IP($ this-getlong());//用户互联网协议(互联网协议)所在范围的开始地址
$ offset=$ this-get long 3();
fseek($this- fp,$ offset);
$ location[ endip ]=long 2 IP($ this-getlong());//用户互联网协议(互联网协议)所在范围的结束地址
$byte=fread($this- fp,1);//标志字节
开关(顺序(字节)){
案例1: //标志字节为1,表示国家和区域信息都被同时重定向
$ country offset=$ this-get long 3();//重定向地址
fseek($this- fp,$ country offset);
$byte=fread($this- fp,1);//标志字节
开关(顺序(字节)){
案例二://标志字节为2,表示国家信息又被重定向
fseek($this- fp,$ this-getlong 3());
$ location[ country ]=$ this-getstring();
fseek($this- fp,$ country offset 4);
$ location[ area ]=$ this-get area();
打破;
默认值://否则,表示国家信息没有被重定向
$ location[ country ]=$ this-getstring($ byte);
$ location[ area ]=$ this-get area();
打破;
打破;
案例二://标志字节为2,表示国家信息被重定向
fseek($this- fp,$ this-getlong 3());
$ location[ country ]=$ this-getstring();
fseek($this- fp,$ offset 8);
$ location[ area ]=$ this-get area();
打破;
默认值://否则,表示国家信息没有被重定向
$ location[ country ]=$ this-getstring($ byte);
$ location[ area ]=$ this-get area();
打破;
if(location[ country ]== CZ88 .NET) { //CZ88 .网表示没有有效信息
$location[country]=未知;
if(location[ area ]= CZ88 .NET) {
$ location[ area ]= ;
返回$位置
调用方式:
?服务器端编程语言(专业超文本预处理器的缩写)
包含“我的位置。PHP”;
回声前
$ IP= 180。76 .6 .130 ;
$ I location=new I location();
$ location=$ I location-get location($ IP);
print _ r($ location);