地理定位查询主要可分为两个步骤:第一,获取待查询的IP;第二,利用MaxMind? API进行查询并返回查询结果。本例中数据比较简单,因此可以把查询结果直接以Javascript字符串的形式返回给客户端,用eval调用即可。下面将详细介绍上述步骤。

1.获取待查询的IP

首先,在文件开始的部分引入MaxMind? API的库文件。


  1. <?php 
  2. //导入库文件  
  3. include("geoipcity.inc");  
  4. include("geoipregionvars.php")  
  5. ?> 

如果未传递任何参数,则使用当前访客的IP,如此就可以在加载的时候使用显示当前访客的信息了。代码如下。


  1. //接上面程序  
  2. //获取客户端IP的函数  
  3. function getClientIP()  
  4. {  
  5.     if (isset($HTTP_SERVER_VARS["HTTP_X_FORWARDED_FOR"]))  
  6.     {  
  7.         $ip = $HTTP_SERVER_VARS["HTTP_X_FORWARDED_FOR"];  
  8.     }  
  9.     elseif (isset($HTTP_SERVER_VARS["HTTP_CLIENT_IP"]))  
  10.     {  
  11.         $ip = $HTTP_SERVER_VARS["HTTP_CLIENT_IP"];  
  12.     }  
  13.     elseif (isset($HTTP_SERVER_VARS["REMOTE_ADDR"]))  
  14.     {  
  15.         $ip = $HTTP_SERVER_VARS["REMOTE_ADDR"];  
  16.     }  
  17.     elseif (getenv("HTTP_X_FORWARDED_FOR"))  
  18.     {  
  19.         $ip = getenv("HTTP_X_FORWARDED_FOR");  
  20.     }  
  21.     elseif (getenv("HTTP_CLIENT_IP"))  
  22.     {  
  23.         $ip = getenv("HTTP_CLIENT_IP");  
  24.     }  
  25.     elseif (getenv("REMOTE_ADDR"))  
  26.     {  
  27.         $ip = getenv("REMOTE_ADDR");  
  28.     }  
  29.     else  
  30.     {  
  31.         $ip = false;  
  32.     }  
  33.     return $ip;  
  34. }  
  35.  
  36. //如果传递的查询参数为空  
  37. if(empty($_GET['q']))  
  38. {  
  39.     $ip = getClientIP();  
  40.     if (!isset($ip))  
  41.     {  
  42.         echo 'alert("Cannot get your IP address!");';  
  43.         die();  
  44.     }  

如果有参数传递,则判断是否为IP或域名信息。如果都不是,报错,终止查询。代码如下。


  1. //接上面程序  
  2. //如果传递的查询参数不为空  
  3. else  
  4. {    //探测字符串是否为IP的正则表达式  
  5.     $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])$/"
    ;  
  6.      
  7.     if(preg_match($pattern, $_GET['q']))        //如果查询的信息为IP  
  8.     {  
  9.         $ip = $_GET['q'];  
  10.     }  
  11.     else     //如果查询的信息为域名  
  12.     {  
  13.         $ip = gethostbyname($_GET['q']);        
    //若域名查询成功,则返回的字符串为IP  
  14.         if(!preg_match($pattern, $ip))              
    //检测是否返回IP,若未返回IP,即域名查询失败,报错  
  15.         {  
  16.             echo 'alert("Invalid Input!"); ';  
  17.             die();  
  18.         }  
  19.     }  

经过以上一系列处理,就可以从参数中获取真实的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 - 地区代码,仅美国可用。

了解数据的组织结构后就可以方便地使用其中的数据了。代码如下:


  1. //接上面程序  
  2.  
  3. //如果取消下一行将使用共享内存打开GeoLiteCity数据库,
    可加快查询。但前提是服务器支持共享内存  
  4. //$gi = geoip_open("./GeoLiteCity.dat",GEOIP_MEMORY_CACHE);  
  5.  
  6. //以常规方式打开GeoLiteCity数据库,一般情况下都可以使用  
  7. $gi = geoip_open("./GeoLiteCity.dat",GEOIP_STANDARD);  
  8.  
  9. //以上是假定GeoLiteCity数据库和PHP文件在同一个目录,
    故使用"./GeoLiteCity.dat"为路径  
  10. //如果不是,请改为实际目录  
  11.  
  12. //获取IP的信息  
  13. $record = geoip_record_by_addr($gi, $ip);    
  14. //关闭数据库  
  15. geoip_close($gi);  
  16.  
  17. //如果获取了相关数据  
  18. if($record)  
  19. {  
  20.     echo 'loadGeoInfo('.  
  21.                '"'.   $_GET['q']   .'",'.          
    //原始查询信息  
  22.                '"'.   $ip   .'",'.                      //被查IP  
  23.                '"'.   $record->country_code   
    .'",'.    //国家代码(两位)  
  24.                '"'.   $record->country_code3  
    .'",'.    //国家代码(三位)  
  25.                '"'.   $record->country_name   
    .'",'.    //国家名称  
  26.                '"'.   $GEOIP_REGION_NAME
    [$record-
    >country_code] [$record->region]   .'",'. 
    //地区名称  
  27.                '"'.   $record->city   .'",'.       
    //城市名称  
  28.                $record->latitude   .','.                //纬度  
  29.                $record->longitude   .')';               //经度  
  30.                                                
    //如果数据库中不存在相关数据  
  31. else  
  32. {  
  33.     echo 'alert("The Information for '.$ip.' is not available now!"); ';  
  34. }  
  35. ?> 

将以上代码整合到一起,保存为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)

稳定

产品高可用性高并发

贴心

项目群及时沟通

专业

产品经理1v1支持

快速

MVP模式小步快跑

承诺

我们选择声誉

坚持

10年专注高端品质开发
  • 返回顶部