寒窗轩,寒川的个人网络博客,记录互联网事,学习网络编程、分享工作经验、人生感悟,包括但不限于程序代码、数据库、Office办公、随笔等内容。

PHP+MySQL基于地理位置信息的附近交友的实现

老早就想总结这篇《PHP+MySQL基于地理位置信息的附近好友交友的实现》的文章了,受限于工作时间问题,今天把它写出来,起个抛砖引玉的作用。我们都知道,基于地理位置信息的APP有很多,例如微信、陌陌等等,本文以小白的视野来探究其功能用PHP+MySQL是怎么实现的?

在开始这个功能实现过程前,本人对微信、陌陌的附近好友功能也进行了一翻研究,其基本原理大致如下:


GPS.png

图1 基于地理位置信息的附近交友的实现原理图


从上图可以看出,用户要获取附近用户列表,需要先获取自生的GPS信息,再把GPS信息提交给WEB服务器,WEB服务器到数据库中查询附近的人,再返回用户列表给用户,这是基本原理。至于如何数据库查询实现基于地理位置信息的附近交友,下面重点讲解。

首先,建议数据库,结构如下:

CREATE TABLE IF NOT EXISTS `nearby` (
  `id` int(11) unsigned NOT NULL,
  `name` varchar(40) NOT NULL COMMENT '用户名',
  `longitude` varchar(10) NOT NULL COMMENT '经度',
  `latitude` varchar(10) NOT NULL COMMENT '纬度'
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

--
-- 转存表中的数据 `nearby`
--

INSERT INTO `nearby` (`id`, `name`, `longitude`, `latitude`) VALUES
(1, 'demo', '12.2222544', '65.54451'),
(2, 'demo1', '12.2222844', '65.54751'),
(3, 'demo2', '12.5222844', '65.55751'),
(4, 'demo3', '12.5226844', '65.58751');

--
-- Indexes for dumped tables
--

--
-- Indexes for table `nearby`
--
ALTER TABLE `nearby`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `nearby`
--
ALTER TABLE `nearby`
  MODIFY `id` int(11) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=5;

为方便说明,本文以轻量级的PHP数据库框架Medoo为数据库链接,安装如下:

composer require catfan/Medoo

安装完成后就开始以PHP编写API了,代码如下:

<?php
require 'vendor/autoload.php';
use Medoo\Medoo;
$database = new Medoo([
    'type' => 'mysql',
    'host' => 'localhost',
    'database' => 'data',
    'username' => 'root',
    'password' => 'password'
]);
//为方便编写,用户ID直接前台传来,实际开发过程中建议使用session或cookie或其它用户验证
$id =isset($_GET['id'])?$_GET['id']:0;
//获取经纬度
$longitude = isset($_GET['longitude'])?$_GET['longitude']:0;
$latitude = isset($_GET['latitude'])?$_GET['latitude']:0;
//更新户自己的GPS信息
$database->update("nearby", [
"longitude" => $longitude,
"latitude" => $latitude
], [
"id" =>$id
]);
//访问以下地址获取附近用户
http://xxx.com/?id=1&longitude=12.2222544&latitude=65.54451
$longitudeAndLatitude = getAround($longitude, $latitude, '100');
$datas = $database->select("account", [
    "user_name",
    "email"
], [
    "user_id[>]" => 100
]);
$list = $database->query("SELECT *,(st_distance(point(longitude,latitude),point('{$longitude}','{$latitude}'))*95000/1000) as distance FROM nearby WHERE id != '{$id}' AND longitude >= '{$longitudeAndLatitude['minLng']}' AND longitude <= '{$longitudeAndLatitude['maxLng']}' AND latitude >= '{$longitudeAndLatitude['minLat']}' AND latitude <= '{$longitudeAndLatitude['maxLat']}' ORDER BY distance ASC limit 10")
->fetchAll();
print_r($database->log());
print_r($list);
/**
*
* 函数:根据经纬度及半径范围(单位:千米)返回坐标
* @param  string $longitude   经度
* @param  string $latitude 纬度
* @param  string $raidus 范围,千米
*
**/
function getAround($longitude, $latitude, $raidus)
{
    $PI = pi();
    $raidus = $raidus*1000;
    $degree = (24901*1609)/360.0;
    $dpmLat = 1/$degree;
    $radiusLat = $dpmLat*$raidus;
    $minLat = $latitude - $radiusLat;
    $maxLat = $latitude + $radiusLat;
    $mpdLng = $degree*cos($latitude * ($PI/180));
    $dpmLng = 1 / $mpdLng;
    $radiusLng = $dpmLng*$raidus;
    $minLng = $longitude - $radiusLng;
    $maxLng = $longitude + $radiusLng;
    return ['minLat'=>$minLat, 'maxLat'=>$maxLat, 'minLng'=>$minLng, 'maxLng'=>$maxLng];
}


文章写得不错?我是土豪我要在线打赏!
在线打赏

昵称:

验证码:验证码

评论:

文章分类
系统
程序
数据
Office
随笔
热门文章
python读取文件夹下图片并生成pdf文件
VB.net开发的word转pdf的小工具
使用python把word转成pdf
文章推荐
免责声明
关于博主
开篇第一章
随机推荐
不合格的emlog插件开发者
我也发个飞信API接口发飞信短消息。
看完电影叶问2之后
毕业实习日记
停电
windows xp win7双系统引导wubi安装ubuntu linux
开场白
.htaccess非伪静态url跳转到伪静态url再伪静态
想说点什么
开篇第一章
友情连接
春燕网络
谢润的博客
企安文档