You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel中用经纬度计算距离(Laravel5.5 SQL查询实现)

在Laravel 5.5中通过SQL计算地理距离的实现

你的思路完全正确——利用Haversine公式(基于经纬度计算两点球面距离)来实现需求,不过在Laravel中处理原生SQL表达式时,有几个细节可以优化,既保证代码安全性又提升可读性。我帮你梳理并优化了代码:

// 假设这是用户的位置经纬度,可根据实际场景动态获取
$userLat = 22.2897874;
$userLng = 70.7583265;

$specialProducts = Products::selectRaw('
        products.id, 
        products.name, 
        products.product_img, 
        products.slug, 
        products.price,
        products.lat,
        products.lng,
        (3959 * ACOS(COS(RADIANS(?)) * COS(RADIANS(products.lat)) * COS(RADIANS(products.lng) - RADIANS(?)) + SIN(RADIANS(?)) * SIN(RADIANS(products.lat)))) AS distance',
    [$userLat, $userLng, $userLat]
)
->join('subcategories', 'subcategories.id', '=', 'products.sub_category_id')
->join('categories', 'categories.id', '=', 'subcategories.category_id')
->join('store', 'store.id', '=', 'products.store_id')
->where('products.status', 1)
->where('products.special', 1)
// 可选:按距离排序,如需优先展示近的商品
->orderBy('distance')
->orderBy('products.created_at', 'DESC')
->get();

关键优化与说明:

  • 用selectRaw()替代直接在select()中写原生SQL:通过参数绑定(?)传递变量,彻底避免SQL注入风险,同时让代码结构更清晰。
  • 替换硬编码的经纬度为变量:这样可以动态传入用户的位置信息,适配不同场景的需求。
  • 公式单位说明:代码中的3959是英里数,如果需要计算公里距离,替换为6371即可。
  • 可选筛选逻辑:如果需要只展示指定范围内的商品,可以添加having条件:
    ->having('distance', '<=', 20) // 筛选20英里内的商品,单位需和公式一致
    

内容的提问来源于stack exchange,提问作者bizz website

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:23:47