Php 递归。每个树枝的最大元素数
我有一个构建递归菜单树的类。数据选择来自以下字段的数据库:Php 递归。每个树枝的最大元素数,php,recursion,Php,Recursion,我有一个构建递归菜单树的类。数据选择来自以下字段的数据库:id,title,id\u parent class Menu { private $db; private $menus_arr = []; public function __construct() { $this->db = new PDO('mysql:host=localhost; dbname=test', 'root', 'admin'); $this->menus_arr = $this-
id
,title
,id\u parent
class Menu {
private $db;
private $menus_arr = [];
public function __construct()
{
$this->db = new PDO('mysql:host=localhost; dbname=test', 'root', 'admin');
$this->menus_arr = $this->getMenus();
echo "<pre>";
print_r($this->menus_arr);
echo "</pre>";
}
private function getMenus()
{
$query = $this->db->prepare("SELECT * FROM menu");
$query->execute();
$result = $query->fetchAll(PDO::FETCH_ASSOC);
// делаем из одномерного массива двумерный, в котором первый ключ - id_parent
$arr = [];
foreach ($result as $value) {
$arr[$value['id_parent']][] = $value;
}
return $arr;
}
public function makeTree($id_parent = 0, $lvl = 0)
{
if (isset($this->menus_arr[$id_parent])) {
foreach ($this->menus_arr[$id_parent] as $value) {
echo "<div class='test' style='margin: 5px 0 5px " . ($lvl * 30) . "px;'>$lvl - " . $value['title'] . "</div>";
$lvl++;
$this->makeTree($value['id'], $lvl);
$lvl--;
}
}
}
表结构:
打印的递归树:
如何确定每个分支的最后一个元素?我们可以通过SQL实现。我们应该使用窗口函数来确定树的最后一个元素 根据您在评论中所写的内容,这是目前最好的猜测:
这是作业还是实际测试?它没有子项?我需要解决这个问题是的,所选元素没有子项,所以您需要单独在php中执行此操作?另一个问题,为什么(例如)“子菜单2”
不算作叶节点?它也没有孩子。我需要通过makeTree()方法完成。谢谢你,Yoshi。这正是我想做的。虽然,不完全正确。已添加到数组['id'=>19,'title'=>m:1.1.3.1','id\u parent'=>7],'id'=>20,'title'=>m:1.1.3.1.1','id\u parent'=>19]@用户381403我更改了答案。它现在计算给定根的最大深度,以便在显示节点时使用。谢谢,Yoshi。
$tree = new Menu();
$tree->makeTree();
<?php
class Menu
{
private $menus_arr = [];
public function __construct()
{
$this->menus_arr = $this->getMenus();
}
private function getMenus()
{
// substitute db access
$result = [
['id' => 1, 'title' => 'm: 1', 'id_parent' => 0],
['id' => 2, 'title' => 'm: 1.1', 'id_parent' => 1],
['id' => 3, 'title' => 'm: 1.1.1', 'id_parent' => 2],
['id' => 4, 'title' => 'm: 1.1.1.1', 'id_parent' => 3],
['id' => 5, 'title' => 'm: 1.1.1.2', 'id_parent' => 3],
['id' => 6, 'title' => 'm: 1.1.2', 'id_parent' => 2],
['id' => 7, 'title' => 'm: 1.1.3', 'id_parent' => 2],
['id' => 19, 'title' => 'm: 1.1.3.1', 'id_parent' => 7],
['id' => 20, 'title' => 'm: 1.1.3.1.1', 'id_parent' => 19],
['id' => 8, 'title' => 'm: 1.2', 'id_parent' => 1],
['id' => 9, 'title' => 'm: 1.3', 'id_parent' => 1],
['id' => 10, 'title' => 'm: 2', 'id_parent' => 0],
['id' => 11, 'title' => 'm: 2.1', 'id_parent' => 10],
['id' => 12, 'title' => 'm: 2.1.1', 'id_parent' => 11],
['id' => 13, 'title' => 'm: 2.1.1.1', 'id_parent' => 12],
['id' => 14, 'title' => 'm: 2.1.2', 'id_parent' => 11],
['id' => 15, 'title' => 'm: 2.2', 'id_parent' => 10],
['id' => 16, 'title' => 'm: 2.3', 'id_parent' => 10],
['id' => 17, 'title' => 'm: 2.3.1', 'id_parent' => 16],
['id' => 18, 'title' => 'm: 2.3.1.1', 'id_parent' => 17],
];
$arr = [];
foreach ($result as $value) {
$arr[$value['id_parent']][] = $value;
}
return $arr;
}
public function makeTree()
{
foreach ($this->menus_arr[0] as $root) {
$this->renderNode($root, 0, $this->getMaxDepth($root));
}
}
/**
* @param array $node
* @param int $depth
* @param int $maxDepth
*/
private function renderNode(array $node, $depth = 0, $maxDepth = 0)
{
printf(
'<div class="test" style="margin: 5px 0 5px %dpx">%s - %s%s</div>',
$depth * 30,
$depth,
$node['title'],
$depth === $maxDepth ? '<--' : ''
);
if (isset($this->menus_arr[$node['id']])) {
foreach ($this->menus_arr[$node['id']] as $child) {
$this->renderNode($child, $depth + 1, $maxDepth);
}
}
}
/**
* @param array $root
*
* @return int
*/
private function getMaxDepth(array $root)
{
$result = 0;
if (isset($this->menus_arr[$root['id']])) {
foreach ($this->menus_arr[$root['id']] as $child) {
$result = max($result, $this->getMaxDepth($child) + 1);
}
}
return $result;
}
}
$tree = new Menu();
$tree->makeTree();