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 - Html Transfer Code
Oct 09 PHP
不用数据库的多用户文件自由上传投票系统(2)
Oct 09 PHP
投票管理程序
Oct 09 PHP
set_include_path在win和linux下的区别
Jan 10 PHP
9个PHP开发常用功能函数小结
Jul 15 PHP
php模拟登陆的实现方法分析
Jan 09 PHP
PHP查询快递信息的方法
Mar 07 PHP
在Mac OS上自行编译安装Apache服务器和PHP解释器
Dec 24 PHP
PHP版本升级到7.x后wordpress的一些修改及wordpress技巧
Dec 25 PHP
PHP读取大文件的几种方法介绍
Oct 27 PHP
yii2简单使用less代替css示例
Mar 10 PHP
PHP页面静态化――纯静态与伪静态用法详解
Jun 05 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通过asort()给关联数组按照值排序的方法
2015/03/18 PHP
php原生数据库分页的代码实例
2019/02/18 PHP
解决JS浮点数运算出现Bug的方法
2013/03/12 Javascript
javascript实用方法总结
2015/02/06 Javascript
浅谈jQuery页面的滚动位置scrollTop、scrollLeft
2015/05/19 Javascript
实例讲解js验证表单项是否为空的方法
2016/01/09 Javascript
Angularjs中使用Filters详解
2016/03/11 Javascript
jQuery实现导航高亮的方法【附demo源码下载】
2016/11/09 Javascript
Bootstrap轮播图的使用和理解4
2016/12/14 Javascript
JavaScript requestAnimationFrame动画详解
2017/09/14 Javascript
在Bootstrap开发框架中使用dataTable直接录入表格行数据的方法
2018/10/25 Javascript
基于JavaScript canvas绘制贝塞尔曲线
2018/12/25 Javascript
微信小程序登录session的使用
2019/03/17 Javascript
swiper Scrollbar滚动条组件详解
2019/09/08 Javascript
javascript实现点击星星小游戏
2019/12/24 Javascript
在Vue里如何把网页的数据导出到Excel的方法
2020/09/30 Javascript
[01:38]女王驾到——至宝魔廷新尊技能&特效展示
2020/06/16 DOTA
Python中的sort()方法使用基础教程
2017/01/08 Python
基于Python的关键字监控及告警
2017/07/06 Python
pip安装Python库时遇到的问题及解决方法
2017/11/23 Python
python机器学习理论与实战(一)K近邻法
2021/01/28 Python
python 根据时间来生成唯一的字符串方法
2019/01/14 Python
在Python中将函数作为另一个函数的参数传入并调用的方法
2019/01/22 Python
python实现手机销售管理系统
2019/03/19 Python
django admin.py 外键,反向查询的实例
2019/07/26 Python
python  ceiling divide 除法向上取整(或小数向上取整)的实例
2019/12/27 Python
PyTorch的自适应池化Adaptive Pooling实例
2020/01/03 Python
HTML5 localStorage使用总结
2017/02/22 HTML / CSS
浅析HTML5 Landmark
2020/09/11 HTML / CSS
蒙蒂塞罗商店:Monticello Shop
2018/11/25 全球购物
汽车维修专业个人求职信范文
2014/01/01 职场文书
个人四风问题整改措施思想汇报
2014/10/04 职场文书
导游词怎么写
2015/02/04 职场文书
毕业季聚会祝酒词!
2019/07/04 职场文书
mysql升级到5.7时,wordpress导数据报错1067的问题
2021/05/27 MySQL
《帝国时代4》赛季预告 新增内容编译器可创造地图
2022/04/03 其他游戏