PHP获取IP所在地区
2013-07-01 11:22
225 查看
转载自http://www.phper.org.cn/?post=88
这是一个PHP获取客户端IP所在地区的类,它能根据IP地址查地区,简单实用。使用示例
示例一:view sourceprint?
1.
$IpLocation
=
new
IpLocation();
2.
$client
=
$IpLocation
->getlocation();
3.
print_r(
$client
);
示例二:view sourceprint?
1.
$IpLocation
=
new
IpLocation(
'../qqwry/QQWry.Dat'
);
2.
$client
=
$IpLocation
->getlocation(
'115.148.101.72'
);
3.
print_r(
$client
);
相关说明
此类要求提供纯真IP数据库,附件包里包含有此数据库。
在线演示
IP地址查询在线演示:http://down.phper.org.cn/ip/
iplocation.class.php
view sourceprint?
001.
class
IpLocation
002.
{
003.
/**
004.
* QQWry.Dat文件指针
005.
* @var resource
006.
*/
007.
var
$fp
;
008.
009.
/**
010.
* 第一条IP记录的偏移地址
011.
* @var int
012.
*/
013.
var
$firstip
;
014.
015.
/**
016.
* 最后一条IP记录的偏移地址
017.
* @var int
018.
*/
019.
var
$lastip
;
020.
021.
/**
022.
* IP记录的总条数(不包含版本信息记录)
023.
* @var int
024.
*/
025.
var
$totalip
;
026.
027.
/**
028.
* 返回读取的长整型数
029.
* @access private
030.
* @return int
031.
*/
032.
function
getlong()
033.
{
034.
$result
=unpack(
'Vlong'
,
fread
(
$this
->fp,4));
//将读取的little-endian编码的4个字节转化为长整型数
035.
return
$result
[
'long'
];
036.
}
037.
038.
/**
039.
* 返回读取的3个字节的长整型数
040.
* @access private
041.
* @return int
042.
*/
043.
function
getlong3()
044.
{
045.
$result
=unpack(
'Vlong'
,
fread
(
$this
->fp,3).
chr
(0));
//将读取的little-endian编码的3个字节转化为长整型数
046.
return
$result
[
'long'
];
047.
}
048.
049.
/**
050.
* 返回压缩后可进行比较的IP地址
051.
* @access private
052.
* @param string $ip
053.
* @return string
054.
*/
055.
function
packip(
$ip
)
056.
{
057.
// 将IP地址转化为长整型数,如果在PHP5中,IP地址错误,则返回False,
058.
// 这时intval将Flase转化为整数-1,之后压缩成big-endian编码的字符串
059.
return
pack(
'N'
,
intval
(
ip2long
(
$ip
)));
//intaval 获取变量的整数值
060.
}
061.
062.
/**
063.
* 返回读取的字符串
064.
* @access private
065.
* @param string $data
066.
* @return string
067.
*/
068.
function
getstring(
$data
=
""
)
069.
{
070.
$char
=
fread
(
$this
->fp,1);
071.
while
(ord(
$char
)> 0)
// 字符串按照C格式保存,以\0结束 ord()得到字符的ASCII码
072.
{
073.
$data
.=
$char
;
// 将读取的字符连接到给定字符串之后
074.
$char
=
fread
(
$this
->fp,1);
075.
}
076.
return
$data
;
077.
}
078.
079.
/**
080.
* 返回地区信息
081.
* @access private
082.
* @return string
083.
*/
084.
function
getarea()
085.
{
086.
$byte
=
fread
(
$this
->fp,1);
// 标志字节
087.
switch
(ord(
$byte
)){
088.
case
0:
// 没有区域信息
089.
$area
=
""
;
090.
break
;
091.
case
1:
092.
case
2:
// 标志字节为1或2,表示区域信息被重定向
093.
fseek
(
$this
->fp,
$this
->getlong3());
094.
$area
=
$this
->getstring();
095.
break
;
096.
default
:
// 否则,表示区域信息没有被重定向
097.
$area
=
$this
->getstring(
$byte
);
098.
break
;
099.
}
100.
return
$area
;
101.
}
102.
103.
/**
104.
* 根据所给 IP 地址或域名返回所在地区信息
105.
* @access public
106.
* @param string $ip
107.
* @return array
108.
*/
109.
function
getlocation(
$ip
=
''
)
110.
{
111.
if
(!
$this
->fp)
return
null;
// 如果数据文件没有被正确打开,则直接返回空
112.
if
(
$ip
==
''
)
$ip
=
$this
->clientIp();
113.
$location
[
'ip'
] =
gethostbyname
(
$ip
);
// 将输入的域名转化为IP地址
114.
$ip
=
$this
->packip(
$location
[
'ip'
]);
// 将输入的IP地址转化为可比较的IP地址
115.
116.
$l
=0;
// 搜索的下边界
117.
$u
=
$this
->totalip;
// 搜索的上边界
118.
$findip
=
$this
->lastip;
// 如果没有找到就返回最后一条IP记录(QQWry.Dat的版本信息)
119.
while
(
$l
<=
$u
)
// 当上边界小于下边界时,查找失败
120.
{
121.
$i
=
floor
((
$l
+
$u
)/ 2);
// 计算近似中间记录
122.
fseek
(
$this
->fp,
$this
->firstip +
$i
* 7);
123.
$beginip
=
strrev
(
fread
(
$this
->fp,4));
// 获取中间记录的开始IP地址
124.
125.
if
(
$ip
<
$beginip
)
// 用户的IP小于中间记录的开始IP地址时
126.
{
127.
$u
=
$i
- 1;
// 将搜索的上边界修改为中间记录减一
128.
}
129.
else
130.
{
131.
fseek
(
$this
->fp,
$this
->getlong3());
132.
$endip
=
strrev
(
fread
(
$this
->fp,4));
// 获取中间记录的结束IP地址
133.
if
(
$ip
>
$endip
)
// 用户的IP大于中间记录的结束IP地址时
134.
{
135.
$l
=
$i
+1;
// 将搜索的下边界修改为中间记录加一
136.
}
137.
else
// 用户的IP在中间记录的IP范围内时
138.
{
139.
$findip
=
$this
->firstip +
$i
* 7;
140.
break
;
// 则表示找到结果,退出循环
141.
}
142.
}
143.
}
144.
145.
/* 获取查找到的IP地理位置信息 */
146.
fseek
(
$this
->fp,
$findip
);
147.
$location
[
'beginip'
] =long2ip(
$this
->getlong());
// 用户IP所在范围的开始地址
148.
$offset
=
$this
->getlong3();
149.
fseek
(
$this
->fp,
$offset
);
150.
$location
[
'endip'
] =long2ip(
$this
->getlong());
// 用户IP所在范围的结束地址
151.
$byte
=
fread
(
$this
->fp,1);
// 标志字节
152.
switch
(ord(
$byte
))
153.
{
154.
case
1:
// 标志字节为1,表示国家和区域信息都被同时重定向
155.
$countryOffset
=
$this
->getlong3();
// 重定向地址
156.
fseek
(
$this
->fp,
$countryOffset
);
157.
$byte
=
fread
(
$this
->fp,1);
// 标志字节
158.
switch
(ord(
$byte
))
159.
{
160.
case
2:
// 标志字节为2,表示国家信息又被重定向
161.
fseek
(
$this
->fp,
$this
->getlong3());
162.
$location
[
'country'
] =
$this
->getstring();
163.
fseek
(
$this
->fp,
$countryOffset
+4);
164.
$location
[
'area'
] =
$this
->getarea();
165.
break
;
166.
default
:
// 否则,表示国家信息没有被重定向
167.
$location
[
'country'
] =
$this
->getstring(
$byte
);
168.
$location
[
'area'
] =
$this
->getarea();
169.
break
;
170.
}
171.
break
;
172.
case
2:
// 标志字节为2,表示国家信息被重定向
173.
fseek
(
$this
->fp,
$this
->getlong3());
174.
$location
[
'country'
] =
$this
->getstring();
175.
fseek
(
$this
->fp,
$offset
+8);
176.
$location
[
'area'
] =
$this
->getarea();
177.
break
;
178.
default
:
// 否则,表示国家信息没有被重定向
179.
$location
[
'country'
] =
$this
->getstring(
$byte
);
180.
$location
[
'area'
] =
$this
->getarea();
181.
break
;
182.
}
183.
184.
if
(
$location
[
'country'
] ==
" CZ88.NET"
)
// CZ88.NET表示没有有效信息
185.
{
186.
$location
[
'country'
] =
"未知"
;
187.
}
188.
if
(
$location
[
'area'
] ==
" CZ88.NET"
)
189.
{
190.
$location
[
'area'
] =
""
;
191.
}
192.
return
$location
;
193.
}
194.
195.
/**
196.
* 获取客户端IP地址
197.
* */
198.
function
clientIp(){
199.
if
(
getenv
(
'HTTP_CLIENT_IP'
)&&
strcasecmp
(
getenv
(
'HTTP_CLIENT_IP'
),
'unknown'
)){
200.
$onlineip
=
getenv
(
'HTTP_CLIENT_IP'
);
201.
}
elseif
(
getenv
(
'HTTP_X_FORWARDED_FOR'
)&&
strcasecmp
(
getenv
(
'HTTP_X_FORWARDED_FOR'
),
'unknown'
)){
202.
$onlineip
=
getenv
(
'HTTP_X_FORWARDED_FOR'
);
203.
}
elseif
(
getenv
(
'REMOTE_ADDR'
)&&
strcasecmp
(
getenv
(
'REMOTE_ADDR'
),
'unknown'
)){
204.
$onlineip
=
getenv
(
'REMOTE_ADDR'
);
205.
}
elseif
(isset(
$_SERVER
[
'REMOTE_ADDR'
])&&
$_SERVER
[
'REMOTE_ADDR'
] &&
strcasecmp
(
$_SERVER
[
'REMOTE_ADDR'
],
'unknown'
)){
206.
$onlineip
=
$_SERVER
[
'REMOTE_ADDR'
];
207.
}
208.
preg_match(
"/[\d\.]{7,15}/"
,
$onlineip
,
$onlineipmatches
);
209.
$onlineip
=
$onlineipmatches
[0] ?
$onlineipmatches
[0] :
'unknown'
;
210.
unset(
$onlineipmatches
);
211.
return
$onlineip
;
212.
}
213.
214.
/**
215.
* 构造函数,打开 QQWry.Dat 文件并初始化类中的信息
216.
* @param string $filename
217.
* @return IpLocation
218.
*/
219.
function
IpLocation(
$filename
=
""
)
220.
{
221.
if
(!
$filename
)
$filename
=dirname(
__FILE__
).
'/qqwry/QQWry.Dat'
;
222.
if
(!
file_exists
(
$filename
))
exit
(
'qqwry.dat is not exists!'
);
223.
if
((
$this
->fp =@
fopen
(
$filename
,
'rb'
))!==false)
224.
{
225.
$this
->firstip =
$this
->getlong();
226.
$this
->lastip =
$this
->getlong();
227.
$this
->totalip =(
$this
->lastip -
$this
->firstip)/ 7;
228.
register_shutdown_function(
array
(&
$this
,
'_IpLocation'
));
229.
}
230.
}
231.
232.
/**
233.
* 析构函数,用于在页面执行结束后自动关闭打开的文件。
234.
*/
235.
function
_IpLocation()
236.
{
237.
fclose(
$this
->fp);
238.
}
239.
}
附件下载:
iplocation.class.rar 2.93MB
« 最近写的一个JS排版工具|
JS判断浏览器版本号»
相关文章:
.htaccess的基本作用及相关语法介绍
PHP邮件接收类的改进
PHP生成二维码图像的类QRcode
网站重新开通,欢迎大家光临。
PHP在线手册
post by
PHPER | 2010-10-18 20:38 Monday | 文章 |
引用地址:
评论
凯凯 2012-06-05 08:58嗯,不错,很ok,谢谢楼主咯~~~
Gavin 2011-09-16 11:48
哈哈
Gavin 2011-09-16 11:44
可以,值得收藏,博主转载你的,没关系吧
流水 2011-04-05 17:34
嗯嗯,正在写一个小程序,要用到IP地址和地理位置,谢谢博主!
闲逛
2010-12-28 19:02
有些地址返回的是国家,有些是国家的省份城市,不知道有没有单纯的返回国家代码的IP数据库
杨银川 2010-11-23 11:45
我用 php调用的时候出现乱码
如何解决?
Array ( [ip] => 115.148.101.72 [beginip] => 115.148.68.0 [endip] => 115.148.127.255 [country] => ??ηʡ?Ӗ݊Њ [area] => ?琅 )博主回复:需要注意编码,如果你用的是utf8编码的话需要进行转换,具体是从gbk到utf8,编码转换可以参考:http://www.phper.org.cn/?post=54
相关文章推荐
- PHP获取IP所在地区
- PHP获取IP所在地区(转)
- PHP获取用户真实 IP , 淘宝IP接口获得ip地理位置(转)
- php之获取访客IP
- linux php cli模式下获取服务器ip
- php获取客户端ip
- php下通过IP获取地理位置的代码(小偷程序)
- PHP中获取客户端IP、服务器IP的方法
- PHP获取ip对应地区和使用网络类型的方法
- PHP获取用户的真实ip
- PHP获取用户客户端真实IP的解决方案
- php获取浏览器信息。获取访客语言。获取访客操作系统。获取访客IP地址。获取访客地理位置。
- php获取浏览器信息。获取访客语言。获取访客操作系统。获取访客IP地址。获取访客地理位置。
- php 中获取远程用户ip的三种方式,并判定ip是否在一定的范围之内
- JAVA/PHP服务器端获取客户端IP
- PHP截取字符串,获取IP,编码转换,获取远程文件内容
- PHP代码如何实现获取真实IP和代理IP
- PHP getenv() 获取IP
- PHP获取客户端的IP
- PHP 获取用户ip