Laravel REST API返回查询数组仅第一条记录问题求助
问题原因
- 核心逻辑错误:你在
foreach循环内部直接执行return语句,第一次循环查询到匹配的药房数据后就立即返回响应、终止程序运行,后续循环完全不会执行,自然只能返回第一条匹配记录。 - 存在的其他隐患:
- 循环内反复查询数据库,产生N+1查询性能问题,数据量较大时接口响应速度会大幅下降
- 直接将变量拼接进
whereRaw的SQL语句,存在SQL注入风险 - 用
get()查询单条药房数据,返回的是集合格式而非单条记录结构,不符合数据预期
修复方案
方案1:最小改动适配原有逻辑
仅调整返回逻辑,不修改查询结构,适合快速修复:
public function index ($id) { // 初始化结果存储数组 $result = []; $gards = DB::table('gards') ->whereRaw('date_from < Now() AND date_to > Now() AND (gard_day = 1 OR gard_night = 1)') ->get(); foreach($gards as $gard) { // 改用参数绑定避免SQL注入,用first()获取单条记录 $pharmacy = DB::table('pharmacies') ->whereRaw("id = ? AND city_id = ?", [$gard->pharmacy_id, $id]) ->first(); // 仅匹配到有效药房时才存入结果集 if (!empty($pharmacy)) { $result[] = $pharmacy; } } // 所有循环执行完成后统一返回结果 return response()->json($result, 200); }
方案2:联表查询优化(更推荐)
直接通过关联查询一次性获取所有符合条件的药房数据,避免循环查库,性能更高、代码更简洁:
public function index ($id) { $pharmacies = DB::table('gards') ->join('pharmacies', 'gards.pharmacy_id', '=', 'pharmacies.id') ->whereRaw('gards.date_from < NOW() AND gards.date_to > NOW() AND (gards.gard_day = 1 OR gards.gard_night = 1)') ->where('pharmacies.city_id', $id) ->select('pharmacies.*') ->distinct() // 避免同一药房多个排班记录导致重复返回 ->get(); return response()->json($pharmacies, 200); }
问题复现快照

内容的提问来源于stack exchange,提问作者Issam
相关产品推荐
相关产品推荐

