当前位置:首页 > PHP

php实现lbs实现商品筛选

2026-02-15 03:26:56PHP

PHP实现LBS商品筛选的方法

数据库设计

在MySQL中存储商品信息时需包含经纬度字段(如latitudelongitude),推荐使用POINT空间数据类型。创建表时可添加空间索引加速查询:

CREATE TABLE products (
    id INT PRIMARY KEY,
    name VARCHAR(255),
    location POINT NOT NULL,
    SPATIAL INDEX(location)
);

距离计算

使用Haversine公式计算两点间距离(单位:公里):

function getDistance($lat1, $lon1, $lat2, $lon2) {
    $earthRadius = 6371;
    $dLat = deg2rad($lat2 - $lat1);
    $dLon = deg2rad($lon2 - $lon1);
    $a = sin($dLat/2) * sin($dLat/2) + 
         cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * 
         sin($dLon/2) * sin($dLon/2);
    $c = 2 * atan2(sqrt($a), sqrt(1-$a));
    return $earthRadius * $c;
}

MySQL空间查询

对于MySQL 5.7+版本,可直接使用ST_Distance_Sphere函数:

php实现lbs实现商品筛选

SELECT 
    id, 
    name,
    ST_Distance_Sphere(location, POINT(:user_lon, :user_lat)) / 1000 AS distance_km
FROM 
    products
WHERE 
    ST_Distance_Sphere(location, POINT(:user_lon, :user_lat)) <= :radius_km * 1000
ORDER BY 
    distance_km;

Redis GEO优化

对高频访问场景可使用Redis GEO数据结构:

$redis->geoAdd('products:locations', $longitude, $latitude, $productId);
$results = $redis->geoRadius('products:locations', $userLon, $userLat, $radius, 'km');

分页处理

结合距离筛选时需注意分页逻辑,建议先获取符合条件的所有ID,再分页查询详细信息:

php实现lbs实现商品筛选

$page = $_GET['page'] ?? 1;
$perPage = 10;
$offset = ($page - 1) * $perPage;

$stmt = $pdo->prepare("
    SELECT SQL_CALC_FOUND_ROWS p.*
    FROM products p
    WHERE ST_Distance_Sphere(location, POINT(?, ?)) <= ? * 1000
    LIMIT ? OFFSET ?
");
$stmt->execute([$userLon, $userLat, $radius, $perPage, $offset]);

性能优化

  1. 确保latitudelongitude字段建立复合索引
  2. 对固定区域商品可先进行地理边界框预筛选
  3. 使用缓存存储热门区域的查询结果
  4. 考虑使用Elasticsearch的geo_point类型实现高级搜索

前端交互

通过浏览器获取用户位置后传递给后端:

navigator.geolocation.getCurrentPosition(position => {
    const {latitude, longitude} = position.coords;
    // 发送AJAX请求到PHP后端
});

完整示例

后端接口处理示例:

// 获取前端传递的经纬度和半径
$userLat = $_GET['lat'];
$userLon = $_GET['lon'];
$radius = $_GET['radius'] ?? 5; // 默认5公里

$products = $pdo->prepare("
    SELECT id, name, 
           ST_Distance_Sphere(location, POINT(?, ?)) / 1000 AS distance
    FROM products
    WHERE ST_Distance_Sphere(location, POINT(?, ?)) <= ? * 1000
    ORDER BY distance
")->execute([$userLon, $userLat, $userLon, $userLat, $radius]);

header('Content-Type: application/json');
echo json_encode($products->fetchAll());

标签: 商品php
分享给朋友:

相关文章

php实现一个

php实现一个

PHP 实现一个简单的计算器 创建一个基本的计算器,支持加、减、乘、除运算。以下是一个完整的实现代码示例: <?php $result = ""; if ($_SERVER["REQUES…

php mvc 实现

php mvc 实现

PHP MVC 实现方法 MVC(Model-View-Controller)是一种设计模式,用于分离应用程序的逻辑、数据和界面。以下是实现PHP MVC框架的关键步骤。 目录结构 创建以下目录结构…

无限分类实现 php

无限分类实现 php

无限分类的实现方法 无限分类通常用于构建多层级结构的数据,如商品分类、部门架构等。以下是几种常见的实现方式: 邻接列表模式(Adjacency List) 邻接列表是最简单的实现方式,通过在每个记录…

php 实现无限分类

php 实现无限分类

无限分类的实现方法 无限分类通常用于构建多层级结构的数据,如商品分类、菜单管理等。以下是几种常见的实现方式: 邻接列表模型(Adjacency List) 这是最简单的实现方式,每个分类记录存储其父…

php 实现md5

php 实现md5

使用 PHP 内置函数实现 MD5 PHP 提供了 md5() 函数,可以直接计算字符串的 MD5 哈希值。该函数接受一个字符串参数,返回 32 字符的十六进制哈希值。 $string = "H…

php session实现购物车

php session实现购物车

PHP Session 实现购物车 初始化 Session 确保在使用 Session 前调用 session_start() 函数。通常放在 PHP 文件的最顶部。 <?php sessio…