TP6接口附近的人功能的实现

星萱大大_5666

星萱大大_5666

2026-08-22

576人浏览

原创

thinkphp6实现“附近的人”功能需存储经纬度并建联合索引,用haversine公式在sql中计算球面距离并按距离排序筛选。

tp6接口附近的人功能的实现

ThinkPHP6 实现“附近的人”功能,核心是基于用户地理位置(经纬度)计算距离,并按距离排序筛选。关键不在 TP6 特性,而在于地理距离算法选型、数据库设计与查询优化。

1. 数据库中存储经纬度并建立索引

用户表需包含 latitude(纬度)、longitude(经度)两个字段,类型建议为 DECIMAL(10,8)(足够精确到几米)或 DOUBLE。避免用字符串或整数存储。

为提升查询效率,在这两个字段上建立联合索引(尤其当数据量大时):

ALTER TABLE `user` ADD INDEX `idx_lat_lng` (`latitude`, `longitude`);

2. 使用“球面余弦定理”或“Haversine 公式”计算距离

MySQL 原生不支持地理距离函数(除非启用 GIS 扩展),推荐在 SQL 中直接使用 Haversine 公式计算两点间球面距离(单位:公里):

示例 SQL(查当前用户(lat=39.9042, lng=116.4074)5公里内其他用户):

SELECT id, nickname, 
  ROUND(
    6371 * ACOS(
      COS(RADIANS(39.9042)) * COS(RADIANS(latitude)) * 
      COS(RADIANS(longitude) - RADIANS(116.4074)) + 
      SIN(RADIANS(39.9042)) * SIN(RADIANS(latitude))
    ), 2
  ) AS distance
FROM `user` 
WHERE latitude IS NOT NULL AND longitude IS NOT NULL
HAVING distance 

TP6 中可用 Query 类或 Db::raw() 封装该逻辑,注意参数需安全绑定防止 SQL 注入。

飞桨PaddlePaddle
飞桨PaddlePaddle

飞桨PaddlePaddle是百度推出的开源深度学习平台。

下载

3. 用“矩形过滤+精确排序”提升性能(推荐)

纯 Haversine 查询无法利用索引,大数据量下会全表扫描。更优做法是先用经纬度范围粗筛(矩形框),再在结果中精确算距排序:

  • 根据目标点和最大距离(如 5km),估算经纬度偏移范围(纬度1°≈111km,经度1°≈111×cos(纬度)km)
  • 先 WHERE 过滤出 lat∈[lat−Δ, lat+Δ] 且 lng∈[lng−Δ, lng+Δ] 的记录
  • 再对子集用 Haversine 计算真实距离并排序

TP6 可这样写(简化示意):

$lat = 39.9042; $lng = 116.4074; $max_km = 5;
$latDelta = $max_km / 111.0;
$lngDelta = $max_km / (111.0 * cos(deg2rad($lat)));
<p>$users = Db::name('user')
->where('latitude', 'between', [$lat - $latDelta, $lat + $latDelta])
->where('longitude', 'between', [$lng - $lngDelta, $lng + $lngDelta])
->field('id,nickname,latitude,longitude')
->select()
->toArray();</p><p>// PHP 端二次过滤 + 排序(小数据量可行)或拼接带 Haversine 的 SQL 子查询</p>

4. 可选:升级 MySQL 5.7+ 启用 ST_Distance_Sphere

若数据库支持 GIS(如 MySQL ≥5.7.6),可将经纬度存为 POINT 类型,并用空间函数:

ALTER TABLE user ADD COLUMN location POINT;
UPDATE user SET location = POINT(longitude, latitude);
ALTER TABLE user ADD SPATIAL INDEX(location);
<p>SELECT id, nickname, 
ROUND(ST_Distance_Sphere(location, POINT(116.4074, 39.9042)) / 1000, 2) AS distance
FROM user 
WHERE ST_Distance_Sphere(location, POINT(116.4074, 39.9042)) </p>

此方式性能更好、语义清晰,但需调整表结构与迁移数据。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

2023.10.19

3028

3

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

2025.10.17

4229

12

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2025.12.29

3649

9

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

2026.01.19

366

15

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

2026.09.23

0

15

Buffalo框架路由与请求处理实操指南
Buffalo框架路由与请求处理实操指南

本专题讲解Buffalo框架路由与请求处理机制,涵盖路由注册与分组、资源路由、Handler编写规范、Context上下文方法、参数绑定、中间件编写挂载、Session与Cookie读写、Flash消息及错误页面定制方法。

2026.09.23

0

15

Buffalo框架零基础入门教程
Buffalo框架零基础入门教程

本专题整理Buffalo框架入门内容,涵盖Go环境准备、buffalo CLI安装、新项目生成、目录结构说明、dev热加载启动、数据库连接配置与常见报错排查,帮助新手按约定优于配置的思路跑通第一个Buffalo框架应用。

2026.09.23

0

15

Conan创建软件包配方指南
Conan创建软件包配方指南

本专题介绍通过conanfile.py创建软件包的方法,讲解包名、版本、依赖和构建设置等基础信息,以及source、build、package、package_info等常用方法的作用及编写思路。

2026.09.22

0

12

Conan二进制包配置指南
Conan二进制包配置指南

本专题介绍Conan根据操作系统、编译器、架构和构建类型生成二进制包的方法,讲解Profile、Settings、Options及Package ID的作用,帮助管理不同平台和编译环境下的包版本。

2026.09.22

0

13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
ThinkPHP6.x 微实战--十天技能课堂
ThinkPHP6.x 微实战--十天技能课堂

共26课时 | 2.5万人学习

ThinkPHP6.x API接口--十天技能课堂
ThinkPHP6.x API接口--十天技能课堂

共14课时 | 1.5万人学习