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

如何在Laravel的select查询中调用自定义函数并传入当前表字段值

Laravel 查询时传入表字段值到自定义距离计算函数的解决方案

问题根源

你当前使用的calcula_distancia是PHP层面定义的函数,会在Laravel构造SQL语句的阶段直接执行,此时数据库查询尚未运行,自然无法获取到participantes表的实时字段值,传入的'participantes.latitude'只会被当作普通字符串处理,这就是你拿到字面量而非字段值的核心原因。

解决方案

方案1:在数据库层面创建自定义函数(推荐)

这种方案将计算逻辑下沉到SQL层,支持对计算结果进行排序、筛选,适合数据量较大的场景。

  1. 首先在你的数据库中创建同名的SQL自定义函数,以MySQL为例,执行以下语句创建函数(逻辑和你PHP中写的距离计算保持一致即可,示例为哈弗曼公式计算公里数):
DELIMITER //
CREATE FUNCTION calcula_distancia(lat1 DOUBLE, lon1 DOUBLE, lat2 DOUBLE, lon2 DOUBLE) 
RETURNS DOUBLE
DETERMINISTIC
BEGIN
    -- 替换为你实际的距离计算逻辑
    RETURN 6371 * acos(
        cos(radians(lat1)) * cos(radians(lat2)) * cos(radians(lon2) - radians(lon1)) 
        + sin(radians(lat1)) * sin(radians(lat2))
    );
END //
DELIMITER ;
  1. 修改Laravel查询代码,使用DB::raw调用SQL函数,原其他查询逻辑保持不变,仅替换select中的距离计算部分即可:
->select(
    // 其他原有字段保持不变
    'unidades.descricao as desc_unid',
    // 使用参数绑定避免SQL注入风险
    DB::raw('calcula_distancia(?, ?, participantes.latitude, participantes.longitude) as distancia', 
        [$ofps[0]->latitude, $ofps[0]->longitude]
    )
)

方案2:查询完成后在PHP集合层面计算

如果你不想改动数据库结构,且数据量不大,可以先查出所有需要的字段,再遍历结果计算距离:

// 原有where、join、select逻辑不变,仅移除select中的距离计算部分,正常分页
$necps = DB::table('necessidades_part')->where('necessidades_part.id_part',"<>",$id_part)
    // 原有逻辑保持不变
    ->orderBy('data','desc')
    ->paginate(10);

// 遍历分页结果计算距离,不会破坏原有分页结构
$mf = new MinhasFuncoes();
$necps->through(function ($item) use ($mf, $ofps) {
    $item->distancia = $mf->calcula_distancia(
        $ofps[0]->latitude,
        $ofps[0]->longitude,
        $item->latitude,
        $item->longitude
    );
    return $item;
});

注意事项

  • 方案1支持直接在SQL中对distancia字段进行排序、where筛选,性能更好,适合大部分业务场景
  • 方案2逻辑全部在PHP中维护,无需改动数据库,但如果需要对距离做筛选、排序,需要先查出全量数据再处理,数据量大时性能较差

内容的提问来源于stack exchange,提问作者Luiz Santa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 20:45:01