Laravel 8 API响应去除数字键:转为纯数组JSON格式
原控制器函数:
public function getStudentsinGrade($grade, $school_id){ $students = Student::where('school_id', $school_id)->get(); $this -> grade = $grade; $gradeStudent= $students->filter(function($value,$key){ return $value->grade == $this->grade; }); if(count($gradeStudent) > 0){ return response()->json($gradeStudent); } else{ return response('No Registered Student'); } }
当前API响应(数字键为问题点):
{ "2": { "id": 14, "student_name": "Polly Grain", "gender": "Female", "stream_id": 1, "school_id": 1, "final_year_id": 2, "grade": "Form Four" }, "3": { "id": 15, "student_name": "Polly Grain", "gender": "Male", "stream_id": 3, "school_id": 1, "final_year_id": 2, "grade": "Form Four" } }
期望响应格式:
[
{
"id": 1,
"student_name": "sae sddat",
"gender": "male",
"stream_id": 2,
"school_id": 10,
"final_year_id": 12,
"grade": "Form One"
},
{
"id": 1,
"student_name": "sae sddat",
"gender": "male",
"stream_id": 2,
"school_id": 10,
"final_year_id": 12,
"grade": "Form One"
},
{
"id": 1,
"student_name": "sae sddat",
"gender": "male",
"stream_id": 2,
"school_id": 10,
"final_year_id": 12,
"grade": "Form One"
}
]
解决方案
核心原因
filter()方法返回的Collection会保留原数据的键名,转JSON时这些键会被保留为对象的属性,导致响应是带数字键的JSON对象而非纯数组。
可选修改方案
方案1:数据库层面直接过滤(推荐)
没必要先查询所有学生再做内存过滤,直接在数据库层面筛选更高效,且get()返回的Collection转JSON会自动生成纯数组:
public function getStudentsinGrade($grade, $school_id){ $gradeStudent = Student::where('school_id', $school_id) ->where('grade', $grade) ->get(); if ($gradeStudent->isNotEmpty()) { return response()->json($gradeStudent); } else { return response('No Registered Student'); } }
方案2:重置Collection键名(适合必须先查全量的场景)
如果业务逻辑需要先获取所有学生再过滤,可调用values()方法重置Collection的键为连续索引,转JSON时就会变成纯数组:
public function getStudentsinGrade($grade, $school_id){ $students = Student::where('school_id', $school_id)->get(); $gradeStudent = $students->filter(function($value) use ($grade) { return $value->grade == $grade; })->values(); // 关键:重置键名 if ($gradeStudent->isNotEmpty()) { return response()->json($gradeStudent); } else { return response('No Registered Student'); } }
这里用use ($grade)代替给$this->grade赋值,代码更简洁规范。
额外优化建议
- 用
isNotEmpty()判断集合是否为空,比count()更符合Laravel的语义化写法。 - 空响应建议返回JSON格式提示,保持接口响应格式统一:
return response()->json(['message' => 'No Registered Student'], 404);
内容的提问来源于stack exchange,提问作者deo_gemini

