如何在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
相关产品推荐
相关产品推荐

