将经纬度附近沙龙查询SQL转换为Laravel Eloquent及DB::select语法
把原生距离查询转换成Laravel的DB门面和Eloquent写法
嘿,我来帮你把这段计算附近沙龙的SQL转换成Laravel里更规范、更安全的写法,不管是用DB门面还是Eloquent ORM都能实现,还能避免SQL注入的风险~
一、DB::select 优化版(安全参数绑定)
你的原生SQL直接拼接变量有SQL注入风险,Laravel的DB门面支持参数绑定,我们可以改成这样:
$lat = 你的纬度值; $lng = 你的经度值; $salons = DB::select(" SELECT *, (3959 * acos( cos( radians(?) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(?) ) + sin( radians(?) ) * sin( radians( lat ) ) )) AS distance FROM salons HAVING distance < 25 ORDER BY distance LIMIT 0 , 3 ", [$lat, $lng, $lat]);
这里用?作为占位符,后面的数组按顺序传入参数,Laravel会自动处理参数绑定,彻底避免注入问题,功能和你的原SQL完全一致。
二、Eloquent ORM 写法(更贴合Laravel模型)
如果你的沙龙数据对应Salon模型(通常在app/Models/Salon.php),用Eloquent会更优雅,也方便后续对模型进行关联、访问器等操作:
use App\Models\Salon; $lat = 你的纬度值; $lng = 你的经度值; $salons = Salon::selectRaw(" *, (3959 * acos( cos( radians(?) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(?) ) + sin( radians(?) ) * sin( radians( lat ) ) )) AS distance ", [$lat, $lng, $lat]) ->havingRaw('distance < ?', [25]) ->orderBy('distance') ->limit(3) ->get();
关键点说明:
selectRaw():用来编写包含原生SQL函数的查询字段,同时支持参数绑定havingRaw():因为distance是查询时计算出来的虚拟字段,不能用普通的having()方法,所以用havingRaw()来处理条件orderBy('distance')和limit(3):和原生SQL的排序、限制逻辑一致,Laravel的查询构造器会帮你转换成对应的SQL- 最终用
get()获取模型集合,得到的结果是Salon模型实例,比DB门面的数组结果更便于Laravel生态的开发
两种写法都能实现你要的“获取25英里范围内最近3个沙龙”的需求,你可以根据自己的场景选择:如果只是简单查询用DB门面就行,要是需要模型的其他功能,Eloquent会更顺手~
内容的提问来源于stack exchange,提问作者Farhan Anees
相关产品推荐
相关产品推荐

