(013)PHP 技巧 * 附近的人功能实现

一、准备

授权获取用户的经纬度并存入数据库(lng 字段、lat 字段)。

二、查询

1. 原生查询

SELECT
    *, CONVERT (
        2 * 6378.137 * ASIN(
            SQRT(
                POW(
                    SIN(
                        3.1415926535898 * (" . $_GET['lat'] . " - lat) / 360
                    ),
                    2
                ) + COS(
                    3.1415926535898 * " . $_GET['lat'] . " / 180
                ) * COS(lat * 3.1415926535898 / 180) * POW(
                    SIN(
                        3.1415926535898 * (" . $_GET['lng'] . " - lng) / 360
                    ),
                    2
                )
            )
        ),
        DECIMAL (10, 2)
    ) AS distance
FROM
    `user`
WHERE
    lat > 0  AND lng > 0
ORDER BY
    distance ASC
LIMIT 0, 10

查询的数据过滤掉指点距离的数据即可,也可使用 where 条件筛选,但 as 的别名不可以作为 条件字段,需要又将计算的语句再写一遍。TP框架为例

2. ThinkPHP5+

// 获取地图 sql
public function getGeoSql($lat,$lng){
    $sql = <<<geo
CONVERT (
    2 * 6378.137 * ASIN(
        SQRT(
            POW(
                SIN(
                    3.1415926535898 * (" . $lat . " - lat) / 360
                ),
                2
            ) + COS(
                3.1415926535898 * " . $lat . " / 180
            ) * COS(lat * 3.1415926535898 / 180) * POW(
                SIN(
                    3.1415926535898 * (" . $lng . " - lng) / 360
                ),
                2
            )
        )
    ),
    DECIMAL (10, 2)
)
geo;
    return $sql;
}

// 获取附近 1000m 的人
public function getLists($params){
    $params = $this->request()->params();
    $lat = $params["lat"] ?? 0;
    $lng = $params["lng"] ?? 0;
    if(!$lat || !$lng){
        return [];
    }
    $geoSql = $this->getGeoSql($params["lat"],$params["lng"]);
    $rs = User::field("*," . $geoSql . "as distance")
        ->where("lng&lat",">",0)
        ->where("$geoSql < 1000")
        ->page($params["page"] ?? 1 , $params["limit"] ?? 10)
        ->orderRaw("distance asc")
        ->select();

    return $rs;
}
发布了57 篇原创文章 · 获赞 43 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/Phplayers/article/details/105563454