如何使用php mysql为这个表创建一个动态树
tbl_folder
db_id db_foldername
1 accounting
2 hr
3 it
tbl_subfolder
db_id db_folderid db_subfoldername
1 1 xxx
2 1 yyy
3 2 zzz
tbl_childsubfolder
db_id db_subfolderid db_childsubfoldername
1 1 ffff
2 2 llll
tbl_subchild
db_id db_childsubfolderid db_subchildname
1 1 eee
2 1 ppp
会计
XXX
YYY
小时
它
包括("包括/ connect.php&#34);
- 选择 -
$名称&#34 ;;
}
?>
if(isset($_POST['add'])){
$foldername=$_POST['txt_name'];
$select=$_POST['txt_select'];echo $select;
$explod=explode("-",$select);
$path=$explod['0'].';'.$explod['1'];
if($path==";"){$path="";}
$parent_id=$explod['1'];
if($foldername==""){echo"enter a name";}
else{
$insert_query=mysqli_query($conn,"insert into tbl_folders(parent_id,path,name)values('$parent_id','$path','$foldername')")or die(mysqli_error($conn));
header("location:index.php");
}
}
$sql=mysqli_query($conn,"select * from tbl_folders where parent_id='0'")or die(mysqli_error($conn));
while($row=mysqli_fetch_array($sql)){
$name=$row['name'];
$id=$row['db_id'];
echo $name;echo"<br/>";
$sqli=mysqli_query($conn,"select * from tbl_folders where parent_id='$id'")or die(mysqli_error($conn));
while($row=mysqli_fetch_array($sqli)){
$name=$row['name'];
$id=$row['db_id'];
$path=$row['path'];
$x=explode(";",$path);echo $path;echo"<br/>";
$pa=$x['1'];
echo $name;echo"<br/>";
$sqli=mysqli_query($conn,"select * from tbl_folders where parent_id='$id' and path='$pa'")or die(mysqli_error($conn));
while($row=mysqli_fetch_array($sqli)){
$name=$row['name'];
$id=$row['db_id'];
$path=$row['db_path'];
echo $name;echo"<br/>";}
}
}
答案 0 :(得分:1)
构建树
您可以使用以下字段构建一个表:
`id (int), parent_id (int), path (vachar), name`
id - 是标识符 parent_id - 指同一个表中父级的id path - 是父ID到给定元素的路径
表中的示例条目:
|id | parent_id | path | name|
-------------------------------
|1 | 0 | | A |
-------------------------------
|2 | 1 |;1; | B |
-------------------------------
|3 | 2 |;1;2; | C |
其中A是父母,B是A的孩子,C是B的孩子。
在后端逻辑中,您需要具备以下条件:
当您在此表中添加/编辑新项目时 - 如果它是根父级(上面没有父级),则使用parent_id=0
和path=''
插入它
当您在此表格中添加/修改新项目时 - 如果它有父项,那么您可以使用parent_id=:idOfParent
和path=CONCAT(:parentPath, ';', :idOfParent, ';')
插入
其中:idOfParent
- 是父ID值,:parentPath
是您与;:idOfParent;
连接的父路径
;
- 是路径中的ID的分隔符
Path列为您提供直接获取给定元素的所有父元素而不使用递归方法的优势。 因此,如果您选择的路径为&#39 ;; 1; 2; 3;&#39;并且您需要父母的信息,您总共会有 1 + 3 SELECT查询。
删除项目时,您可以这样做:
DELETE FROM table WHERE path LIKE (';:deleteId;')
其中:deletedId
是已删除元素的ID。此查询将删除已将已删除项目作为父项的所有条目。
树的可视化
您可以使用此查询获取$ data
'SELECT id, parent_id, path, name FROM table WHERE 1;'
但是对于测试我使用以下示例数组
$data = [
0 => ['id' => 1, 'parent_id' => 0, 'path' => '', 'name' => 'A'],
1 => ['id' => 2, 'parent_id' => 1, 'path' => ';1;', 'name' => 'B'],
2 => ['id' => 3, 'parent_id' => 2, 'path' => ';1;2;', 'name' => 'C'],
3 => ['id' => 4, 'parent_id' => 3, 'path' => ';1;2;3;', 'name' => 'D'],
4 => ['id' => 5, 'parent_id' => 1, 'path' => ';1;', 'name' => 'E'],
5 => ['id' => 6, 'parent_id' => 2, 'path' => ';1;2;', 'name' => 'G'],
6 => ['id' => 7, 'parent_id' => 0, 'path' => '', 'name' => 'H'],
];
$ref = null;
$tree = [];
foreach($data as $item) {
if($item['path']) {
$path = ltrim($item['path'], ';');
$path = rtrim($path, ';');
$pathArray = explode(';', $path);
$i = 0;
foreach($pathArray as $parentId) {
if($i === 0) {
if(!isset($tree[$parentId])) {$tree[$parentId] = ['name' => [], 'children' => []];}
$ref = &$tree[$parentId]['children'];
}
else {
if(!isset($ref[$parentId])) $ref[$parentId] = ['name' => [], 'children' => []];
$ref = &$ref[$parentId]['children'];
}
$i++;
}
if($ref !== null) {
$ref[$item['id']]['name'] = $item['name'];
$ref[$item['id']]['children'] = [];
}
}
else {
$tree[$item['id']]['name'] = $item['name'];
$tree[$item['id']]['children'] = [];
}
}
输出部分:
print '<pre>';
print_r($tree);
print '</pre>';
因此,您可以根据需要更改代码。以您希望的方式打印它(可能需要重新访问以访问每个树节点)