PHP+MySQL+orgChart.js家谱网站:单分支显示问题求助
家谱网站多分支显示问题修复
问题描述
开发基于PHP、MySQL和orgChart.js的家谱网站,通过parent_id字段关联父级(如ID为1的Jone的子女parent_id为1),需要展示多层后代关系,但目前仅能显示一个分支,无法展示所有分支。
数据表结构
| id | name | parent_id |
|---|---|---|
| 1 | Jone | null |
| 2 | Max | 1 |
| 3 | Kane | 1 |
| 4 | Gale | 2 |
Jone是父亲,Max是Jone的儿子,Gale是Jone的孙子。
现有代码
index.php
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Family Tree</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/orgchart/2.1.9/js/jquery.orgchart.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/orgchart/2.1.9/css/jquery.orgchart.min.css"> <style> #chart-container { width: 100%; height: 500px; } </style> </head> <body> <h2>Family Tree</h2> <div id="chart-container"></div> <script> $(function() { $.ajax({ url: 'fetch_family_tree.php', type: 'GET', dataType: 'json', success: function(data) { $('#chart-container').orgchart({ 'data': data, 'depth': 5, 'nodeContent': 'name' }); } }); }); </script> </body> </html>
fetch_family_tree.php
<?php include 'db.php'; $sql = "SELECT id, name, parent_id FROM family_tree"; $result = mysqli_query($connection, $sql); $family_tree = array(); while ($row = mysqli_fetch_assoc($result)) { $id = $row['id']; $name = $row['name']; $parent_id = $row['parent_id']; if ($parent_id === NULL) { $family_tree[$id] = array( 'id' => $id, 'name' => $name, 'children' => array() ); } else { if (!isset($family_tree[$parent_id]['children'])) { $family_tree[$parent_id]['children'] = array(); } $family_tree[$parent_id]['children'][] = array( 'id' => $id, 'name' => $name, 'children' => array() ); } } function addDescendants(&$node, $family_tree) { if (isset($node['children'])) { foreach ($node['children'] as &$child) { if (isset($family_tree[$child['id']]['children'])) { addDescendants($family_tree[$child['id']], $family_tree); } } } } foreach ($family_tree as &$node) { addDescendants($node, $family_tree); } mysqli_close($connection); $root_node = reset($family_tree); echo json_encode($root_node); ?>
问题根源
addDescendants递归函数逻辑错误:仅调用递归但未将子节点的后代赋值给当前节点的子节点,导致只有第一个分支的后代被正确关联,其他分支的后代未被添加到层级结构中。
修复后的代码
修改后的fetch_family_tree.php
<?php include 'db.php'; $sql = "SELECT id, name, parent_id FROM family_tree"; $result = mysqli_query($connection, $sql); // 先将所有节点存入数组,便于通过ID快速查找 $all_nodes = []; $root_node = null; while ($row = mysqli_fetch_assoc($result)) { $all_nodes[$row['id']] = [ 'id' => $row['id'], 'name' => $row['name'], 'children' => [] ]; // 标记根节点 if ($row['parent_id'] === null) { $root_node = &$all_nodes[$row['id']]; } } // 为每个节点绑定对应的父节点 foreach ($all_nodes as $node_id => $node) { $parent_id = $node['parent_id']; if ($parent_id !== null && isset($all_nodes[$parent_id])) { $all_nodes[$parent_id]['children'][] = &$all_nodes[$node_id]; } } mysqli_close($connection); echo json_encode($root_node); ?>
修复说明
- 先将所有节点存入数组,通过ID可直接定位任意节点
- 遍历节点时,将每个子节点直接关联到其父节点的
children数组中 - 这种方式确保所有分支的节点都能被正确纳入层级结构,orgChart.js即可正常渲染所有分支
内容的提问来源于stack exchange,提问作者Geek Fools
相关产品推荐
相关产品推荐

