PHP处理多维数组转JSON,基于MySQL表生成FullCalendar树形资源结构
解决FullCalendar Timeline树形资源数据生成与PHP多维数组转JSON问题
我来帮你搞定这个需求!要把MySQL里的扁平资源数据转成FullCalendar Timeline需要的树形结构,再输出成JSON,咱们分步骤来:
首先,先理清楚你的数据结构:表中的parent字段关联id,用来表示资源的层级关系(比如Auditorium D是父节点,Room D1/D2是子节点)。咱们的目标是把这些扁平的查询结果转换成嵌套的children结构,同时处理好多维数组转JSON的细节。
完整PHP实现代码
// 假设你的PDO连接已经初始化完成($connect变量) $query = "SELECT id, building, title, parent FROM resources ORDER BY id"; $statement = $connect->prepare($query); $statement->execute(); // 用FETCH_ASSOC获取关联数组,操作更直观 $result = $statement->fetchAll(PDO::FETCH_ASSOC); // 第一步:创建节点映射表,快速通过ID查找节点 $nodes = []; foreach ($result as $row) { // 初始化每个节点,默认children为空数组 $nodes[$row['id']] = [ 'id' => (string)$row['id'], // FullCalendar推荐用字符串ID,避免类型歧义 'building' => $row['building'], 'title' => $row['title'], 'children' => [] ]; } // 第二步:构建树形结构 $tree = []; foreach ($result as $row) { $parentId = $row['parent']; // 假设parent为0或空值时是顶级节点,根据你的表结构调整这个判断 if ($parentId === 0 || empty($parentId)) { $tree[] = $nodes[$row['id']]; } else { // 确保父节点存在,避免报错 if (isset($nodes[$parentId])) { $nodes[$parentId]['children'][] = $nodes[$row['id']]; // 子节点不需要重复显示building字段,这里移除它 unset($nodes[$row['id']]['building']); } } } // 第三步:转换为JSON,保留中文等特殊字符不转义 $jsonData = json_encode($tree, JSON_UNESCAPED_UNICODE); // 如果需要格式化输出方便调试,可以用这个: // $jsonData = json_encode($tree, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); echo $jsonData;
代码说明
- 节点映射表:把每个资源节点按
id存到数组里,这样后续查找父节点的效率是O(1),比每次遍历整个数组找父节点高效得多。 - 树形构建逻辑:遍历每个节点,判断它是顶级节点还是子节点:
- 顶级节点直接加入最终的
tree数组; - 子节点则挂载到对应父节点的
children数组中。
- 顶级节点直接加入最终的
- 冗余字段处理:根据你给出的示例,子节点不需要
building字段,所以用unset移除这个字段,让输出结构和需求完全匹配。 - JSON转换细节:用
JSON_UNESCAPED_UNICODE参数确保中文等非ASCII字符不会被转义成\uxxxx格式,保证JSON可读性;如果需要调试,加上JSON_PRETTY_PRINT可以输出格式化的JSON。
测试示例
假设你的表数据如下:
| id | building | title | parent |
|---|---|---|---|
| 1 | 460 Bryant | Auditorium D | 0 |
| 2 | 460 Bryant | Room D1 | 1 |
| 3 | 460 Bryant | Room D2 | 1 |
运行代码后输出的JSON会是:
[ { "id": "1", "building": "460 Bryant", "title": "Auditorium D", "children": [ { "id": "2", "title": "Room D1", "children": [] }, { "id": "3", "title": "Room D2", "children": [] } ] } ]
完全符合FullCalendar Timeline需要的树形资源结构。
注意事项
- 调整
parent判断条件:如果你的表中顶级节点的parent是NULL而不是0,把判断改成$parentId === null即可。 - 处理无效父节点:如果存在
parent指向不存在的id的情况,代码里的isset($nodes[$parentId])会跳过这些节点,避免报错。
内容的提问来源于stack exchange,提问作者Alexander Frolov
相关产品推荐
相关产品推荐

