Laravel API返回结构调整:嵌套对象转对象数组问题排查
Laravel接口grades字段结构调整问题
我开发了Laravel框架下的TODreport方法,调用API后返回的JSON里grades字段是嵌套对象结构,但需要改成对象数组结构,每个数组元素要包含grade_name字段。以下是相关代码和结果,请帮忙修正。
实现代码
public function TODreport($school_id, $date) { $school = School::where('id', $school_id)->first(); $school_education_level = $school->educationLevel; $result =['message' => 'Attendance Report in School']; $levels = [ 'Standard One', 'Standard Two', 'Standard Three', 'Standard Four', 'Standard Five', 'Standard Six', 'Standard Seven', ]; if($school_education_level == 'Secondary') { $levels = ['Form One', 'Form Two', 'Form Three', 'Form Four']; } foreach($levels as $level) { $result['grades'][$level] = []; $result['grades'][$level]['total_students'] = AttendanceStudent::where('dateofattendance', $date) ->where('school_id', $school_id) ->where('grade', $level ) ->count(); $result['grades'][$level]['total_boys_present_in_class'] = AttendanceStudent::where('dateofattendance', $date) ->where('school_id', $school_id) ->where('attendance_id', "1") ->where('grade', $level ) ->whereHas('student' , function($query){ return $query->where('gender', 'male'); }) ->count(); $result['grades'][$level]['total_girls_present_in_class'] = AttendanceStudent::where('dateofattendance', $date) ->where('school_id', $school_id) ->where('attendance_id', "1") ->where('grade', $level ) ->whereHas('student' , function($query){ return $query->where('gender', 'female'); }) ->count(); $result['grades'][$level]['total_boys_absent_in_class'] = AttendanceStudent::where('dateofattendance', $date) ->where('school_id', $school_id) ->where('attendance_id', "2") ->where('grade', $level ) ->whereHas('student' , function($query){ return $query->where('gender', 'male'); }) ->count(); $result['grades'][$level]['total_girls_absent_in_class'] = AttendanceStudent::where('dateofattendance', $date) ->where('school_id', $school_id) ->where('attendance_id', "2") ->where('grade', $level ) ->whereHas('student' , function($query){ return $query->where('gender', 'female'); }) ->count(); } }
当前返回结果
{ "message": "Attendance Report in School", "grades": { "Form One": { "total_students": 0, "total_boys_present_in_class": 0, "total_girls_present_in_class": 0, "total_boys_absent_in_class": 0, "total_girls_absent_in_class": 0 }, "Form Two": { "total_students": 0, "total_boys_present_in_class": 0, "total_girls_present_in_class": 0, "total_boys_absent_in_class": 0, "total_girls_absent_in_class": 0 }, "Form Three": { "total_students": 0, "total_boys_present_in_class": 0, "total_girls_present_in_class": 0, "total_boys_absent_in_class": 0, "total_girls_absent_in_class": 0 }, "Form Four": { "total_students": 0, "total_boys_present_in_class": 0, "total_girls_present_in_class": 0, "total_boys_absent_in_class": 0, "total_girls_absent_in_class": 0 } }, "total_students_in_school": 0, "total_present_students": 0, "total_boys_present": 0, "total_girls_present": 0, "total_absent_students": 0, "total_boys_absent": 0, "total_girls_absent": 0 }
期望返回结果
{ "message": "Attendance Report in School", "grades": [ { "grade_name": "Form One", "total_students": 0, "total_boys_present_in_class": 0, "total_girls_present_in_class": 0, "total_boys_absent_in_class": 0, "total_girls_absent_in_class": 0 }, { "grade_name": "Form Two", "total_students": 0, "total_boys_present_in_class": 0, "total_girls_present_in_class": 0, "total_boys_absent_in_class": 0, "total_girls_absent_in_class": 0 }, { "grade_name": "Form Three", "total_students": 0, "total_boys_present_in_class": 0, "total_girls_present_in_class": 0, "total_boys_absent_in_class": 0, "total_girls_absent_in_class": 0 }, { "grade_name": "Form Four", "total_students": 0, "total_boys_present_in_class": 0, "total_girls_present_in_class": 0, "total_boys_absent_in_class": 0, "total_girls_absent_in_class": 0 } ], "total_students_in_school": 0, "total_present_students": 0, "total_boys_present": 0, "total_girls_present": 0, "total_absent_students": 0, "total_boys_absent": 0, "total_girls_absent": 0 }
解决方案
问题出在循环里的数组赋值方式:原来的代码把$result['grades']作为关联数组,用年级名称作为键;现在需要改成索引数组,每个元素是包含grade_name的对象。
修改步骤:
- 先初始化
$result['grades']为空数组:在循环前添加$result['grades'] = []; - 循环内不再用年级名称作为键,而是创建一个临时数组,加入
grade_name字段,再把这个临时数组push到$result['grades']中
修改后的代码:
public function TODreport($school_id, $date) { $school = School::where('id', $school_id)->first(); $school_education_level = $school->educationLevel; $result =['message' => 'Attendance Report in School']; // 初始化grades为索引数组 $result['grades'] = []; $levels = [ 'Standard One', 'Standard Two', 'Standard Three', 'Standard Four', 'Standard Five', 'Standard Six', 'Standard Seven', ]; if($school_education_level == 'Secondary') { $levels = ['Form One', 'Form Two', 'Form Three', 'Form Four']; } foreach($levels as $level) { // 创建当前年级的统计数组,包含grade_name $gradeData = [ 'grade_name' => $level, 'total_students' => AttendanceStudent::where('dateofattendance', $date) ->where('school_id', $school_id) ->where('grade', $level ) ->count(), 'total_boys_present_in_class' => AttendanceStudent::where('dateofattendance', $date) ->where('school_id', $school_id) ->where('attendance_id', "1") ->where('grade', $level ) ->whereHas('student' , function($query){ return $query->where('gender', 'male'); }) ->count(), 'total_girls_present_in_class' => AttendanceStudent::where('dateofattendance', $date) ->where('school_id', $school_id) ->where('attendance_id', "1") ->where('grade', $level ) ->whereHas('student' , function($query){ return $query->where('gender', 'female'); }) ->count(), 'total_boys_absent_in_class' => AttendanceStudent::where('dateofattendance', $date) ->where('school_id', $school_id) ->where('attendance_id', "2") ->where('grade', $level ) ->whereHas('student' , function($query){ return $query->where('gender', 'male'); }) ->count(), 'total_girls_absent_in_class' => AttendanceStudent::where('dateofattendance', $date) ->where('school_id', $school_id) ->where('attendance_id', "2") ->where('grade', $level ) ->whereHas('student' , function($query){ return $query->where('gender', 'female'); }) ->count(), ]; // 将当前年级数据加入grades数组 $result['grades'][] = $gradeData; } // 记得返回$result(原代码缺失返回逻辑,这里补上) return response()->json($result); }
额外优化建议
当前代码每个年级要执行5次数据库查询,性能较差。可以通过一次查询获取该学校当天所有年级的考勤数据,再分组统计,减少数据库交互次数:
// 获取该学校当天所有考勤记录,预加载student关联 $attendanceRecords = AttendanceStudent::with('student') ->where('dateofattendance', $date) ->where('school_id', $school_id) ->get(); foreach($levels as $level) { // 筛选当前年级的记录 $levelRecords = $attendanceRecords->where('grade', $level); $gradeData = [ 'grade_name' => $level, 'total_students' => $levelRecords->count(), 'total_boys_present_in_class' => $levelRecords->where('attendance_id', 1)->where('student.gender', 'male')->count(), 'total_girls_present_in_class' => $levelRecords->where('attendance_id', 1)->where('student.gender', 'female')->count(), 'total_boys_absent_in_class' => $levelRecords->where('attendance_id', 2)->where('student.gender', 'male')->count(), 'total_girls_absent_in_class' => $levelRecords->where('attendance_id', 2)->where('student.gender', 'female')->count(), ]; $result['grades'][] = $gradeData; }
内容的提问来源于stack exchange,提问作者deo_gemini
相关产品推荐
相关产品推荐

