本文介绍一种健壮、通用的 php 方法,用于将结构不固定的 json 数据(可能包含嵌套对象或纯字符串值)自动转换为语义清晰的 html 表格,兼容多层级、混合类型数据,避免因类型不一致导致的 foreach 错误。
本文介绍一种健壮、通用的 php 方法,用于将结构不固定的 json 数据(可能包含嵌套对象或纯字符串值)自动转换为语义清晰的 html 表格,兼容多层级、混合类型数据,避免因类型不一致导致的 foreach 错误。
在实际开发中(如医疗检验报告、动态表单导出等场景),后端常需将结构不可预知的 JSON 数据渲染为 HTML 表格。问题核心在于:JSON 可能同时包含 对象(section → key/value 对) 和 纯字符串值(如 "Ex. Directo Gram":"Negativo"),而原始代码未做类型判断,直接对非数组值调用 foreach,从而触发 Warning: foreach() argument must be of type array|object, null given。
✅ 正确处理逻辑:双路径分支判断
关键在于对每个顶层键值对执行 类型检测:
- 若值为数组(即一个“分组”),则遍历其内部键名生成
(格式:"分组名/字段名"),并遍历其值生成 ; - 若值为字符串(即单个独立字段),则直接以该键作为表头("字段名"),值作为单元格内容。
✅ 完整可运行示例代码
<?php // ✅ 修复后的 $request_2(已补全缺失引号,确保 JSON 合法) $request_2 = '{ "URINA II (Exame Sumário da Urina)": { "Cor": "Amarela", "Aspecto": "Límpido", "Densidade": "1.021", "pH": "7.0", "Proteínas": "Vestígios", "Glucose": "Negativo", "Corpos Cetónicos": "Negativo", "Urobilinogénio": "Negativo", "Bilirrubina": "Negativo", "Nitritos": "Negativo", "Esterase leucocitária (Leucócitos)": "+ +", "Hemoglobina": "+ +" }, "Exame do Sedimento": { "Células Epiteliais": "0-2/campo", "Leucócitos": "15 - 25/campo", "Eritrócitos": "15-25/campo" }, "Urina, Exame Microbiológico (Urocultura)": { "Células epiteliais": "0-2/campo", "Leucócitos": "15 - 25/campo", "Eritrócitos": "15-25/campo" }, "Ex. Directo Gram": "Negativo", "URINA E DOSEAMENTOS URINÁRIOS": { "Ex. Cultural Resultado": "Negativo" } }'; $obj = json_decode($request_2, true); // ✅ 验证 JSON 解析是否成功 if (json_last_error() !== JSON_ERROR_NONE) { die('Invalid JSON: ' . json_last_error_msg()); } // 开始生成表格 echo '<table border="1" class="data-table">'; echo '<thead><tr>'; // 第一阶段:构建表头 <th> foreach ($obj as $section => $values) { if (is_array($values)) { // 分组内字段 → "Section/Field" foreach ($values as $field => $value) { echo '</th> <th>' . htmlspecialchars($section . '/' . $field) . '</th>'; } } else { // 单值字段 → 直接使用键名(无斜杠) echo '<th>' . htmlspecialchars($section) . '</th>'; } } echo '</tr></thead>'; echo '<tbody><tr>'; // 第二阶段:填充数据行 <td> foreach ($obj as $section => $values) { if (is_array($values)) { // 遍历分组内所有值 foreach ($values as $value) { echo '</td> <td>' . htmlspecialchars((string)$value) . '</td>'; } } else { // 单值直接输出 echo '<td>' . htmlspecialchars((string)$values) . '</td>'; } } echo '</tr></tbody>'; echo ''; ?>⚠️ 关键注意事项
- JSON 合法性优先:务必使用 json_decode(..., true) 并检查 json_last_error(),避免解析失败导致 $obj 为 null。
- XSS 防护:所有输出到 HTML 的内容必须经 htmlspecialchars() 转义,防止脚本注入。
- 类型强制转换:对非字符串值(如数字、布尔)统一转为 (string),避免 echo 时隐式转换异常。
- 空值容错:可在循环前增加 isset($values) 判断,进一步提升鲁棒性。
-
样式与语义:建议添加 border 或 CSS 类(如 class="data-table")便于后续样式控制;若需响应式,可配合
或现代 CSS Grid/Flex 布局。
此方案完全解耦于 JSON 结构,无需预先定义字段列表,适用于任何深度为 1~2 层的混合型键值数据,是构建动态报告系统的核心基础能力。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











