3.2.2 利用GeoIP数据库及API进行地理定位查询
地理定位查询主要可分为两个步骤:***,获取待查询的IP;第二,利用MaxMind? API进行查询并返回查询结果。本例中数据比较简单,因此可以把查询结果直接以Javascript字符串的形式返回给客户端,用eval调用即可。下面将详细介绍上述步骤。
1.获取待查询的IP
首先,在文件开始的部分引入MaxMind? API的库文件。<?php
//导入库文件
include("geoipcity.inc");
include("geoipregionvars.php")
?>
如果未传递任何参数,则使用当前访客的IP,如此就可以在加载的时候使用显示当前访客的信息了。代码如下。//接上面程序
//获取客户端IP的函数
function getClientIP()
{
if (isset($HTTP_SERVER_VARS["HTTP_X_FORWARDED_FOR"]))
{
$ip= $HTTP_SERVER_VARS["HTTP_X_FORWARDED_FOR"];
}
elseif (isset($HTTP_SERVER_VARS["HTTP_CLIENT_IP"]))
{
$ip= $HTTP_SERVER_VARS["HTTP_CLIENT_IP"];
}
elseif (isset($HTTP_SERVER_VARS["REMOTE_ADDR"]))
{
$ip= $HTTP_SERVER_VARS["REMOTE_ADDR"];
}
elseif (getenv("HTTP_X_FORWARDED_FOR"))
{
$ip=getenv("HTTP_X_FORWARDED_FOR");
}
elseif (getenv("HTTP_CLIENT_IP"))
{
$ip=getenv("HTTP_CLIENT_IP");
}
elseif (getenv("REMOTE_ADDR"))
{
$ip=getenv("REMOTE_ADDR");
}
else
{
$ip=false;
}
return $ip;
}
//如果传递的查询参数为空
if(empty($_GET['q']))
{
$ip=getClientIP();
if (!isset($ip))
{
echo 'alert("Cannot get your IP address!");';
die();
}
}
如果有参数传递,则判断是否为IP或域名信息。如果都不是,报错,终止查询。代码如下。//接上面程序
//如果传递的查询参数不为空
else
{ //探测字符串是否为IP的正则表达式
$pattern="/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\
.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2
[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/";
if(preg_match($pattern, $_GET['q'])) //如果查询的信息为IP
{
$ip= $_GET['q'];
}
else //如果查询的信息为域名
{
$ip=gethostbyname($_GET['q']);
//若域名查询成功,则返回的字符串为IP
if(!preg_match($pattern, $ip))
//检测是否返回IP,若未返回IP,即域名查询失败,报错
{
echo 'alert("Invalid Input!"); ';
die();
}
}
}
经过以上一系列处理,就可以从参数中获取真实的IP用于查询了。
2.通过IP获取地理信息
利用MaxMind?取得某IP的地理信息是相对容易的,查询的结果是一个结构体,包含国家代码、国家名称、城市名称和城市经纬度等信息。下面对其中元素进行一一说明。
country_code - 国家代码(两位),如中国为CN。
country_code3 - 国家代码(三位),如中国为CHN。
country_name - 国家名称(英文),如中国为China。
region - 区域代码,通过$GEOIP_REGION_NAME[$record->country_code] [$record->region]可获得区域的名称。对于中国,region得到的是省级行政区的名称,如$GEOIP_REGION_NAME["CN"]["01"]对应的行政区即位Anhui(安徽)。
city - 城市名称。
postal_code - 邮编,仅美国可用。
latitude - 纬度。
longitude - 经度。
dma_code - DMA代码,仅美国可用。
area_code - 地区代码,仅美国可用。
了解数据的组织结构后就可以方便地使用其中的数据了。代码如下://接上面程序
//如果取消下一行将使用共享内存打开GeoLiteCity数据库,
可加快查询。但前提是服务器支持共享内存
//$gi=geoip_open("./GeoLiteCity.dat",GEOIP_MEMORY_CACHE);
//以常规方式打开GeoLiteCity数据库,一般情况下都可以使用
$gi=geoip_open("./GeoLiteCity.dat",GEOIP_STANDARD);
//以上是假定GeoLiteCity数据库和PHP文件在同一个目录,
故使用"./GeoLiteCity.dat"为路径
//如果不是,请改为实际目录
//获取IP的信息
$record=geoip_record_by_addr($gi, $ip);
//关闭数据库
geoip_close($gi);
//如果获取了相关数据
if($record)
{
echo 'loadGeoInfo('.
'"'. $_GET['q'] .'",'.
//原始查询信息
'"'. $ip .'",'. //被查IP
'"'. $record->country_code
.'",'. //国家代码(两位)
'"'. $record->country_code3
.'",'. //国家代码(三位)
'"'. $record->country_name
.'",'. //国家名称
'"'. $GEOIP_REGION_NAME
[$record->country_code] [$record->region] .'",'.
//地区名称
'"'. $record->city .'",'.
//城市名称
$record->latitude .','. //纬度
$record->longitude .')'; //经度
//如果数据库中不存在相关数据
else
{
echo 'alert("The Information for '.$ip.' is not available now!"); ';
}
?>
将以上代码整合到一起,保存为search.php,放到本程序的主目录中(search.php完整代码在光盘中本章节目录里可以找到)。
在浏览器中输入http://服务器地址/程序所在路径/search.php?q=google.com,应该会显示与下面信息类似的输出结果。
loadGeoInfo("google.com", "64.233.187.99", "US", "USA", "United States", "California", "Mountain View", 37.4192,-122.0574)
而输入http://服务器地址/程序所在路径/search.php?q=202.114.64.139,则输出应该和下面类似。
loadGeoInfo("202.114.64.139", "202.114.64.139", "CN", "CHN", "China", "Hubei", "Wuhan" ,30.5833, 114.2667)
【责任编辑:云霞 TEL:(010)68476606】
点赞 0