PHP安装GeoIP扩展根据IP获取地理位置及计算距离的方法


Posted in PHP onJuly 01, 2016

根据IP获取访客所在国家/城市/经纬度
安装GeoIP扩展:

sudo apt-get install libgeoip-dev
pecl install geoip-1.1.0

注意:Beta版要指定版本号.如果是apt安装的PHP,直接安装php5-geoip这个包即可.
php.ini中加入:

extension=geoip.so
geoip.custom_directory="/usr/share/GeoIP"

免费下载GeoLiteCity数据库(解压后18MB):
http://dev.maxmind.com/geoip/legacy/install/city/

wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
gunzip GeoLiteCity.dat.gz
sudo mkdir -v /usr/share/GeoIP
sudo mv -v GeoLiteCity.dat /usr/share/GeoIP/GeoIPCity.dat

测试:

php -a
<?php
print_r(geoip_record_by_name('106.37.165.80')); //回车后按Ctrl+D运行
Array
(
 [continent_code] => AS
 [country_code] => CN
 [country_code3] => CHN
 [country_name] => China //国家
 [region] => 22
 [city] => Beijing //城市
 [postal_code] =>
 [latitude] => 39.928901672363 //纬度
 [longitude] => 116.38829803467 //经度
 [dma_code] => 0
 [area_code] => 0
)

在命令行用geoiplookup查看IP信息:

traceroute www.oschina.net

可见IP地址

61.145.122.155
sudo apt-get install geoip-bin geoip-database
geoiplookup 61.145.122.155 -f /usr/share/GeoIP/GeoIP.dat
GeoIP Country Edition: CN, China

geoip-database提供的GeoIP.dat只能精确到国家.

geoiplookup 61.145.122.155 -f /usr/share/GeoIP/GeoIPCity.dat
GeoIP City Edition, Rev 1: CN, 30, Guangdong, Guangzhou, N/A, 23.116699, 113.250000, 0, 0

从maxmind官网下的数据库GeoLiteCity则信息更详细.

geoiplookup 61.145.122.155 则同时显示上述两个数据库的信息.

根据IP确定经纬度与计算距离

可以用

geoip_record_by_name($_SERVER['REMOTE_ADDR'])

根据用户IP确定经纬度.
注意:

geoip_record_by_name()

返回的西经和南纬是负数.

5000米转成经纬度:
纬度 Latitude:  1 deg = 110852 m
经度 Longitude: 1 deg = 111320*cos(lat) m
同一经线上,相差一纬度约为 110852 米
同一纬线上,相差一经度约为 111320*cos(lat) 米 (lat为该纬线的纬度)

<?php
//以当前用户经纬度为中心,查询5000米内的其他用户
$y = 5000 / 110852; //纬度的范围
$x = 5000 / (111320*cos($lat)); //经度的范围
$sql = '
 select * from user where 
 lat >= ($lat-$y) and lat <= ($lat+$y) and 
 lon >= ($lon-$x) and lon <= ($lon+$x);
';

数据库用户表中设两个字段,分别存储用户的经度lat和纬度lon.

($lat-$y) <= lat <= ($lat+$y)
($lon-$x) <= lon <= ($lon+$x)

这个范围是一个粗略的范围,下面计算距离后把超过5公里的用户去掉即可.

根据上面查询出来的用户的经纬度,
用半正矢公式(Haversine)根据经纬度计算两点间距离:

<?php
function distance($lat1, $lon1, $lat2, $lon2) {
 $R = 6371393; //地球平均半径,单位米
 $dlat = deg2rad($lat2-$lat1);
 $dlon = deg2rad($lon2-$lon1);
 $a = pow(sin($dlat/2), 2) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * pow(sin($dlon/2), 2);
 $c = 2 * atan2(sqrt($a), sqrt(1-$a));
 $d = $R * $c;
 return round($d);
}
echo distance(0, 0, -1, 0); // 111202米

然后就可以用uasort或array_multisort由近到远列出用户了,比如有名为win,osx,lin这3个用户:

<?php
$arr = array(
 'win' => array(
  'dis' => 1024,
  'age' => 31
 ),
 'osx' => array(
  'dis' => 512,
  'age' => 15
 ),
 'lin' => array(
  'dis' => 512,
  'age' => 25
 )
);
foreach($arr as $k => $v) {
 $sort['dis'][$k] = $v['dis'];
 $sort['age'][$k] = $v['age'];
}
//先按距离升序排序,如果距离相同,则按年龄降序排序
array_multisort($sort['dis'], SORT_ASC, $sort['age'], SORT_DESC, $arr);
echo json_encode($arr);
//{"lin":{"dis":512,"age":25},"osx":{"dis":512,"age":15},"win":{"dis":1024,"age":31}}
PHP 相关文章推荐
用php随机生成福彩双色球号码的2种方法
Feb 04 PHP
php实现上传图片生成缩略图示例
Apr 13 PHP
php使用GD创建保持宽高比缩略图的方法
Apr 17 PHP
PHP YII框架开发小技巧之模型(models)中rules自定义验证规则
Nov 16 PHP
如何使用php脚本给html中引用的js和css路径打上版本号
Nov 18 PHP
对比分析php中Cookie与Session的异同
Feb 19 PHP
PHP文件上传类实例详解
Apr 08 PHP
php构造方法中析构方法在继承中的表现
Apr 12 PHP
php表单加入Token防止重复提交的方法分析
Oct 10 PHP
PHP读取CSV大文件导入数据库的实例
Jul 24 PHP
ThinkPHP框架使用redirect实现页面重定向的方法实例分析
Apr 12 PHP
laravel框架创建授权策略实例分析
Nov 22 PHP
php投票系统之增加与删除投票(管理员篇)
Jul 01 #PHP
PHP读书笔记_运算符详解
Jul 01 #PHP
php+MySql实现登录系统与输出浏览者信息功能
Jul 01 #PHP
php无法连接mysql数据库的正确解决方法
Jul 01 #PHP
Apache无法自动跳转却显示目录的解决方法
Nov 30 #PHP
Windows2003下php5.4安装配置教程(IIS)
Jun 30 #PHP
Windows2003下php5.4安装配置教程(Apache2.4)
Jun 30 #PHP
You might like
php压缩HTML函数轻松实现压缩html/js/Css及注意事项
2013/01/27 PHP
php中并发读写文件冲突的解决方案
2013/10/25 PHP
php计算程序运行时间的简单例子分享
2014/05/10 PHP
利用PHP将部分内容用星号替换
2020/04/21 PHP
php防止sql注入的方法详解
2017/02/20 PHP
JSQL SQLProxy 的 php 版本代码
2010/05/05 Javascript
基于JQuery的访问WebService的代码(可访问Java[Xfire])
2010/11/19 Javascript
JavaScript使用IEEE 标准进行二进制浮点运算产生莫名错误的解决方法
2011/05/28 Javascript
fckeditor粘贴Word时弹出窗口取消的方法
2014/10/30 Javascript
深入理解JavaScript系列(34):设计模式之命令模式详解
2015/03/03 Javascript
javascript设置和获取cookie的方法实例详解
2016/01/05 Javascript
js+css绘制颜色动态变化的圈中圈效果
2016/01/27 Javascript
使用JQuery实现智能表单验证功能
2016/03/08 Javascript
Javascript中获取浏览器类型和操作系统版本等客户端信息常用代码
2016/06/28 Javascript
JavaScript中的splice方法用法详解
2016/07/20 Javascript
AngularJS基础 ng-focus 指令简单示例
2016/08/01 Javascript
JavaScript实现Fly Bird小游戏
2016/12/15 Javascript
JS实现下拉菜单列表与登录注册弹窗效果
2017/08/10 Javascript
一步步教你利用Canvas对图片进行处理
2017/09/19 Javascript
详解微信小程序中的页面代码中的模板的封装
2017/10/12 Javascript
python写入xml文件的方法
2015/05/08 Python
查看django版本的方法分享
2018/05/14 Python
numpy给array增加维度np.newaxis的实例
2018/11/01 Python
Django用户认证系统 User对象解析
2019/08/02 Python
postman和python mock测试过程图解
2020/02/22 Python
python 写一个水果忍者游戏
2021/01/13 Python
CSS3制作皮卡丘动画壁纸的示例
2020/11/02 HTML / CSS
班组长安全职责
2014/01/05 职场文书
二手书店创业计划书
2014/01/16 职场文书
《从现在开始》教学反思
2014/04/15 职场文书
习近平在党的群众路线教育实践活动总结大会上的讲话全文
2014/10/25 职场文书
2014年学生资助工作总结
2014/12/18 职场文书
婚育证明样本
2015/06/16 职场文书
入党转正申请自我鉴定
2019/06/25 职场文书
探讨Java中的深浅拷贝问题
2021/06/26 Java/Android
Golang Web 框架Iris安装部署
2022/08/14 Python