如何在Eloquent的selectRaw()方法中插入变量$TotalDistance
Eloquent selectRaw 中传入动态变量的正确实现
原代码的核心问题
- 手动截断单引号拼接变量到SQL字符串的写法,本质是无转义把变量值直接嵌入查询语句。受PHP语法规则限制(单引号包裹的内容不会解析内部的PHP变量),这种写法极易触发SQL语法错误;哪怕换成双引号让PHP直接解析变量,也会因为缺乏自动转义机制存在SQL注入风险。
- 重复调用
hasMany()关联方法,会让同一份关联逻辑拆成两次独立数据库查询,造成不必要的性能损耗。
标准安全写法
selectRaw() 方法本身原生支持参数绑定,完全不需要手动拼接变量到SQL字符串中:方法第一个参数写带占位符的SQL表达式,第二个参数传入占位符对应的绑定值数组,框架会自动处理值的转义与类型适配。
示例代码:
public function totalPace() { // 仅实例化一次关联查询对象,避免重复创建关联实例 $runRelation = $this->hasMany(Runners_List::class, 'run_list_id'); $TotalDistance = $runRelation->sum('distance'); // 用?作为占位符,将变量通过第二个参数绑定传入 $TotalPace = $runRelation->selectRaw( 'SEC_TO_TIME( SUM( TIME_TO_SEC( `pace` ) ) / ? ) as total', [$TotalDistance] )->value('total'); return $TotalPace; }
效率优化方案
从配速计算的业务逻辑看,总配速的计算公式为「所有配速的总换算秒数 / 所有记录的总跑量」,而总跑量本身就是同一张关联表的聚合值,完全可以把两层聚合计算合并到同一条SQL中,省去两次查询的开销,也无需手动传递PHP变量:
public function totalPace() { return $this->hasMany(Runners_List::class, 'run_list_id') ->selectRaw( 'SEC_TO_TIME( SUM( TIME_TO_SEC( `pace` ) ) / SUM(`distance`) ) as total' ) ->value('total'); }
内容的提问来源于stack exchange,提问作者PendejoTrax
相关产品推荐
相关产品推荐

