<?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) {
        // Если текущий ребенок сам является родителем
        if (array_key_exists($child['id'], $data)) {
            // восстановить связь
            $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'];
        if (!array_key_exists($parent, $res)) {
            $res[$parent] = make($parent);
            if (array_key_exists($parent, $data)) {
                $res[$parent]['title'] = $data[$parent]['title'];
            }
        }
        unset($item['parent_id']);
        array_push($res[$parent]['child'], $item);
    }
    $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);
