Вы можете сделать это путем преобразования родительских отношений в дочерние отношения.Для этого вам понадобится одна итерация.Вы можете использовать эту функцию для этого:
function toTree($arrItems) {
$children = [];
foreach($arrItems as $item) $children[$item["parent_id"]][] = $item["id"];
return $children;
}
Затем, получив такую структуру данных, вы можете преобразовать ее в свою структуру HTML с помощью следующей функции:
function toHTML(&$children, $parent=0, $indent="") {
if (!isset($children[$parent])) return "";
return "$indent<ul>\n" . implode("", array_map(function($id) use ($children, $indent) {
return "$indent <li>$id\n" . toHTML($children, $id, "$indent ") . "$indent </li>\n";
}, $children[$parent])) . "$indent</ul>\n";
}
Пример использования:
$arrItems = [
['id' => 1, 'parent_id' => 0],
['id' => 2, 'parent_id' => 1],
['id' => 3, 'parent_id' => 2],
['id' => 4, 'parent_id' => 1],
];
echo toHTML(toTree($arrItems));
Вышеуказанные выходы:
<ul>
<li>1
<ul>
<li>2
<ul>
<li>3
</li>
</ul>
</li>
<li>4
</li>
</ul>
</li>
</ul>