Показать с помощью php генеалогическое дерево, хранящееся в базе данных

У меня есть таблица в моей базе данных (MySQL) со следующей схемой:

-----------------------------
- id  name         parent_id
-----------------------------
- 1   grandfather  NULL
- 2   father       1
- 3   uncle        1
- 4   son          2
- 5   brother      2
- 6   sister       2

И я хочу показать это на своей странице следующим образом:

grandfather
father
son
brother
sister
Uncle

(обход предзаказа)

Это лучшее решение, к которому я пришел (не работает)

$sql = "SELECT p1.id, p1.name, p1.parent_id FROM tree p1 ORDER BY p1.id";
$result = $conn->query($sql);

while($row = mysqli_fetch_assoc($result)) {
arbol($row, $result);
};
function arbol($fila, $result) {
echo $fila["name"] . "<br>";
$flag = false;
while($busqueda = mysqli_fetch_row($result)) {
if($busqueda[2]==$fila["id"]){
$flag = true;
break;
}
};

if ($flag){
foreach ($result as $ruta) {
if($ruta["parent_id"]==$fila["id"]){
arbol($ruta, $result);
};
};


} else {
return;
}
};
};

В результате этого я получаю первый обход до дна, но не до остального дерева:

Grandfather
parent
son

Что я делаю не так? Или что ты мне предлагаешь?

Примечание: когда это закончится, у меня будет много «дедов», поэтому есть время (я бы добавил условие «parent_id = NULL»).

Редактировать:
структура строк после этого:

while( $row = mysqli_fetch_assoc( $result)){
$resguard[] = $row;
}
print_r($resguard);

это (отформатировано для ясности):

Array (
[0] => Array ( [id] => 1 [name] => Grandfather [parent_id] => )
[1] => Array ( [id] => 2 [name] => Parent [parent_id] => 1 )
[2] => Array ( [id] => 3 [name] => Uncle [parent_id] => 1 )
[3] => Array ( [id] => 4 [name] => Son [parent_id] => 2 )
[4] => Array ( [id] => 5 [name] => Brother [parent_id] => 2 )
[5] => Array ( [id] => 6 [name] => Sister [parent_id] => 2 )
)

0

Решение

Вот пример, который работает с вашим набором данных и предполагает, что необработанные данные сортируются по идентификатору (как и ваш запрос). Я полагаю, что путь состоит в том, чтобы написать маленькие (er), простые (r) функции, которые преобразуют данные в дерево и обходят их шаг за шагом. Вероятно, возможно сделать обход массива и напечатать его одним прыжком, как вы делаете, но мой мозг не может придумать хороший способ в данный момент.

function make_tree($data) {
$tree = [];

foreach ($data as $node) {
insert($tree, $node);
}

return $tree;
}

function insert(&$root, &$node) {
if (!$root) {
$root = $node;
}
else if ($root["id"] === $node["parent_id"]) {
$root["children"][] = $node;
}
else if (array_key_exists("children", $root)) {
foreach ($root["children"] as &$c) {
if (insert($c, $node)) {
break;
}
}
}
}

function preorder(&$root) {
if ($root) {
yield $root;

if (array_key_exists("children", $root)) {
foreach ($root["children"] as $c) {
yield from preorder($c);
}
}
}
}

$data = [
["id" => 1, "name" => "Grandfather", "parent_id" => null],
["id" => 2, "name" => "Father", "parent_id" => 1],
["id" => 3, "name" => "Uncle", "parent_id" => 1],
["id" => 4, "name" => "Son", "parent_id" => 2],
["id" => 5, "name" => "Brother", "parent_id" => 2],
["id" => 6, "name" => "Sister", "parent_id" => 2]
];

$tree = make_tree($data);

foreach (preorder($tree) as $node) {
echo $node["name"]."\n";
}

Выход:

Grandfather
Father
Son
Brother
Sister
Uncle

Вот РЕПЛ.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]