
本文讲解如何在 php 中将使用 questionid 作为键的关联数组,转换为连续数字索引的纯数组,从而生成符合预期结构的 json 响应。
本文讲解如何在 php 中将使用 questionid 作为键的关联数组,转换为连续数字索引的纯数组,从而生成符合预期结构的 json 响应。
在处理多对一关系(如一道题目对应多个答案)时,常见做法是先用主键(如 QuestionId)作为临时键构建关联数组,便于去重和聚合。但最终输出 JSON 时,若保留该动态键(如 "1", "2"),会导致前端接收到嵌套过深、结构异常的对象,而非期望的扁平化数组。
问题代码中关键错误在于:
array_push($quest_arr['data'], $questions);
这会将整个 $questions(一个以 QuestionId 为键的关联数组)作为一个元素推入 data 数组,导致 data 变成 [ { "1": {...}, "2": {...} } ] —— 即外层数组仅含一个对象,而该对象内部才是带字符串键的题库。
✅ 正确解法是:跳过 array_push,直接将 $questions 转为索引数组并赋值给 data:
if ($num > 0) {
$quest_arr['error'] = 'false';
$quest_arr['message'] = 'Success';
$questions = [];
foreach ($result as $r) {
$qid = (int)$r['QuestionId']; // 确保键为整型,避免类型混淆
if (!isset($questions[$qid])) {
$questions[$qid] = [
'QuestionId' => $qid,
'question' => $r['QuestionName'],
'answers' => []
];
}
// 注意:若 AnswerID 可能为 NULL,建议显式过滤或保留 null(按业务需求)
$questions[$qid]['answers'][] = $r['AnswerID'];
}
// ✅ 关键修复:移除动态键,转为纯索引数组
$quest_arr['data'] = array_values($questions);
echo json_encode($quest_arr, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);
} else {
echo json_encode([
'error' => 'true',
'message' => 'Error'
]);
}
? 核心要点说明:
-
array_values($questions)丢弃所有原始键(1,2,3),重置为从0开始的连续整数索引,使结果变为[ {...}, {...}, {...} ]; - 直接赋值
$quest_arr['data'] = array_values($questions),而非array_push(...),避免嵌套一层对象; - 推荐添加
JSON_UNESCAPED_UNICODE防止中文被编码为\uXXXX,提升可读性; - 对
QuestionId显式(int)强制转换,避免因字符串键(如'1')与整型键(1)混用引发意外行为。
? 额外建议(健壮性增强):
若数据库中存在重复 QuestionId 但 QuestionName 不一致的情况,当前逻辑会以首次出现为准。如需校验一致性,可在 !isset() 分支中加入断言:
} else if ($questions[$qid]['question'] !== $r['QuestionName']) {
throw new Exception("Inconsistent question name for QuestionId {$qid}");
}
通过以上调整,即可输出完全符合目标结构的 JSON:data 是一个标准数组,每个元素均为不含外层键的对象,便于前端直接遍历渲染。











