<?php
///gist.github.com/max-dark/f39028cc106ed32e8ce1b55a11643b43
/**восстанавливает дерево по таблице связей
* @param $data array
* @return array
*/
function restore_tree($data)
{
$lst = prepare_parents($data);
foreach ($lst as &$parent) {
restore_tree_impl($parent, $lst);
}
return $lst[null];
}
/** восстановление связей родитель->дети
* @param $parent array
* @param $data array
* @return void
*/
function restore_tree_impl(&$parent, &$data) {
foreach ($parent['child'] as &$child) {
// Если текущий ребенок сам является родителем
// восстановить связь
$child['child'] = $data[$child['id']]['child'];
// проверить детей
restore_tree_impl($child, $data);
} else {
$child['child'] = [];
}
}
}
function make($id) {
return ['id' => $id, 'title' => '[root]', 'child' => []];
}
/**Создает список узлов, имеющих датей
* @param $data $data
* @return array
*/
function prepare_parents($data) {
$res = [];
foreach ($data as $item) {
$parent = $item['parent_id'];
$res[$parent] = make($parent);
$res[$parent]['title'] = $data[$parent]['title'];
}
}
unset($item['parent_id']); }
$data = $res;
return $data;
}
function show($item, $level) {
if ($item['id'] === null) return;
while ($level --> 0) {
echo '..';
}
echo $item['title'].PHP_EOL;
}
function print_tree($data, $level = -1) {
show($data, $level);
foreach ($data['child'] as $item) {
print_tree($item, $level + 1);
}
}
$data = [
['id'=>0, 'title'=>'Электроника', 'parent_id' => null],
['id'=>1, 'title'=>'Компьютеры', 'parent_id' => 0],
['id'=>2, 'title'=>'ПК', 'parent_id' => 1],
['id'=>3, 'title'=>'Ноутбуки', 'parent_id' => 1],
['id'=>4, 'title'=>'Мобильные телефоны', 'parent_id' => 0],
['id'=>5, 'title'=>'Бытовая химия', 'parent_id' => null],
['id'=>6, 'title'=>'Порошок', 'parent_id' => 5],
['id'=>7, 'title'=>'Мыло', 'parent_id' => 5],
['id'=>8, 'title'=>'Трансформеры', 'parent_id' => 3],
];
$root = restore_tree($data);
print_tree($root);
PD9waHAKLy8vZ2lzdC5naXRodWIuY29tL21heC1kYXJrL2YzOTAyOGNjMTA2ZWQzMmU4Y2UxYjU1YTExNjQzYjQzCgovKirQstC+0YHRgdGC0LDQvdCw0LLQu9C40LLQsNC10YIg0LTQtdGA0LXQstC+INC/0L4g0YLQsNCx0LvQuNGG0LUg0YHQstGP0LfQtdC5CiAqIEBwYXJhbSAkZGF0YSBhcnJheQogKiBAcmV0dXJuIGFycmF5CiAqLwpmdW5jdGlvbiByZXN0b3JlX3RyZWUoJGRhdGEpCnsKICAgICRsc3QgPSBwcmVwYXJlX3BhcmVudHMoJGRhdGEpOwoKICAgIGZvcmVhY2ggKCRsc3QgYXMgJiRwYXJlbnQpIHsKICAgICAgICByZXN0b3JlX3RyZWVfaW1wbCgkcGFyZW50LCAkbHN0KTsKICAgIH0KICAgIHJldHVybiAkbHN0W251bGxdOwp9CgovKiog0LLQvtGB0YHRgtCw0L3QvtCy0LvQtdC90LjQtSDRgdCy0Y/Qt9C10Lkg0YDQvtC00LjRgtC10LvRjC0+0LTQtdGC0LgKICogQHBhcmFtICRwYXJlbnQgYXJyYXkKICogQHBhcmFtICRkYXRhIGFycmF5CiAqIEByZXR1cm4gdm9pZAogKi8KZnVuY3Rpb24gcmVzdG9yZV90cmVlX2ltcGwoJiRwYXJlbnQsICYkZGF0YSkgewogICAgZm9yZWFjaCAoJHBhcmVudFsnY2hpbGQnXSBhcyAmJGNoaWxkKSB7CiAgICAgICAgLy8g0JXRgdC70Lgg0YLQtdC60YPRidC40Lkg0YDQtdCx0LXQvdC+0Log0YHQsNC8INGP0LLQu9GP0LXRgtGB0Y8g0YDQvtC00LjRgtC10LvQtdC8CiAgICAgICAgaWYgKGFycmF5X2tleV9leGlzdHMoJGNoaWxkWydpZCddLCAkZGF0YSkpIHsKICAgICAgICAgICAgLy8g0LLQvtGB0YHRgtCw0L3QvtCy0LjRgtGMINGB0LLRj9C30YwKICAgICAgICAgICAgJGNoaWxkWydjaGlsZCddID0gJGRhdGFbJGNoaWxkWydpZCddXVsnY2hpbGQnXTsKICAgICAgICAgICAgLy8g0L/RgNC+0LLQtdGA0LjRgtGMINC00LXRgtC10LkKICAgICAgICAgICAgcmVzdG9yZV90cmVlX2ltcGwoJGNoaWxkLCAkZGF0YSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJGNoaWxkWydjaGlsZCddID0gW107CiAgICAgICAgfQogICAgfQp9CmZ1bmN0aW9uIG1ha2UoJGlkKSB7CiAgICByZXR1cm4gWydpZCcgPT4gJGlkLCAndGl0bGUnID0+ICdbcm9vdF0nLCAnY2hpbGQnID0+IFtdXTsKfQovKirQodC+0LfQtNCw0LXRgiDRgdC/0LjRgdC+0Log0YPQt9C70L7Qsiwg0LjQvNC10Y7RidC40YUg0LTQsNGC0LXQuQogKiBAcGFyYW0gJGRhdGEgJGRhdGEKICogQHJldHVybiBhcnJheQogKi8KZnVuY3Rpb24gcHJlcGFyZV9wYXJlbnRzKCRkYXRhKSB7CiAgICAkcmVzID0gW107CiAgICBmb3JlYWNoICgkZGF0YSBhcyAkaXRlbSkgewogICAgICAgICRwYXJlbnQgPSAkaXRlbVsncGFyZW50X2lkJ107CiAgICAgICAgaWYgKCFhcnJheV9rZXlfZXhpc3RzKCRwYXJlbnQsICRyZXMpKSB7CiAgICAgICAgICAgICRyZXNbJHBhcmVudF0gPSBtYWtlKCRwYXJlbnQpOwogICAgICAgICAgICBpZiAoYXJyYXlfa2V5X2V4aXN0cygkcGFyZW50LCAkZGF0YSkpIHsKICAgICAgICAgICAgICAgICRyZXNbJHBhcmVudF1bJ3RpdGxlJ10gPSAkZGF0YVskcGFyZW50XVsndGl0bGUnXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1bnNldCgkaXRlbVsncGFyZW50X2lkJ10pOwogICAgICAgIGFycmF5X3B1c2goJHJlc1skcGFyZW50XVsnY2hpbGQnXSwgJGl0ZW0pOwogICAgfQogICAgJGRhdGEgPSAkcmVzOwogICAgcmV0dXJuICRkYXRhOwp9CgpmdW5jdGlvbiBzaG93KCRpdGVtLCAkbGV2ZWwpIHsKICAgIGlmICgkaXRlbVsnaWQnXSA9PT0gbnVsbCkgcmV0dXJuOwogICAgd2hpbGUgKCRsZXZlbCAtLT4gMCkgewogICAgICAgIGVjaG8gJy4uJzsKICAgIH0KICAgIGVjaG8gJGl0ZW1bJ3RpdGxlJ10uUEhQX0VPTDsKfQoKZnVuY3Rpb24gcHJpbnRfdHJlZSgkZGF0YSwgJGxldmVsID0gLTEpIHsKICAgIHNob3coJGRhdGEsICRsZXZlbCk7CiAgICBmb3JlYWNoICgkZGF0YVsnY2hpbGQnXSBhcyAkaXRlbSkgewogICAgICAgIHByaW50X3RyZWUoJGl0ZW0sICRsZXZlbCArIDEpOwogICAgfQp9CgokZGF0YSA9IFsKICAgIFsnaWQnPT4wLCAndGl0bGUnPT4n0K3Qu9C10LrRgtGA0L7QvdC40LrQsCcsICdwYXJlbnRfaWQnID0+IG51bGxdLAogICAgWydpZCc9PjEsICd0aXRsZSc9PifQmtC+0LzQv9GM0Y7RgtC10YDRiycsICdwYXJlbnRfaWQnID0+IDBdLAogICAgWydpZCc9PjIsICd0aXRsZSc9PifQn9CaJywgJ3BhcmVudF9pZCcgPT4gMV0sCiAgICBbJ2lkJz0+MywgJ3RpdGxlJz0+J9Cd0L7Rg9GC0LHRg9C60LgnLCAncGFyZW50X2lkJyA9PiAxXSwKICAgIFsnaWQnPT40LCAndGl0bGUnPT4n0JzQvtCx0LjQu9GM0L3Ri9C1INGC0LXQu9C10YTQvtC90YsnLCAncGFyZW50X2lkJyA9PiAwXSwKICAgIFsnaWQnPT41LCAndGl0bGUnPT4n0JHRi9GC0L7QstCw0Y8g0YXQuNC80LjRjycsICdwYXJlbnRfaWQnID0+IG51bGxdLAogICAgWydpZCc9PjYsICd0aXRsZSc9PifQn9C+0YDQvtGI0L7QuicsICdwYXJlbnRfaWQnID0+IDVdLAogICAgWydpZCc9PjcsICd0aXRsZSc9PifQnNGL0LvQvicsICdwYXJlbnRfaWQnID0+IDVdLAogICAgWydpZCc9PjgsICd0aXRsZSc9PifQotGA0LDQvdGB0YTQvtGA0LzQtdGA0YsnLCAncGFyZW50X2lkJyA9PiAzXSwKXTsKCiRyb290ID0gcmVzdG9yZV90cmVlKCRkYXRhKTsKCnByaW50X3RyZWUoJHJvb3QpOwo=