Как получить вложенный список HTML из набора записей массива объектов?

У меня есть этот массив объектов, возвращаемых SQL-запросом, где top_id – это мое родительское поле ID:

Array ( [0] => stdClass Object ( [id] => 1 [top_id] => 0 [name] => Cat 1 ) [1] => stdClass Object ( [id] => 2 [top_id] => 0 [name] => Cat 2 ) [2] => stdClass Object ( [id] => 3 [top_id] => 0 [name] => Cat 3 ) [3] => stdClass Object ( [id] => 4 [top_id] => 2 [name] => Subcat 1 ) [4] => stdClass Object ( [id] => 5 [top_id] => 2 [name] => Subcat 2 ) [5] => stdClass Object ( [id] => 6 [top_id] => 3 [name] => Subcat 3 ) [6] => stdClass Object ( [id] => 7 [top_id] => 5 [name] => Subcat 4 ) ) 

Теперь мне нужно получить вложенный список, подобный этому, используя PHP:

 <ul> <li>Cat 1</li> <li>Cat 2 <ul> <li>Subcat 1</li> <li>Subcat 2 <ul> <il>Subcat 3 <ul> <li>Subcat 4</li> </ul> </li> </ul> </li> </ul> </li> <li>Cat 3</li> </ul> 

Есть идеи? благодаря

Solutions Collecting From Web of "Как получить вложенный список HTML из набора записей массива объектов?"

Прежде всего сопоставьте объекты с новым хешем (массивом), в котором индексом является id :

 // map the array onto hash $hash = array(); foreach($array as $object) { $hash[$object->id] = array('object' => $object); } 

Затем перенесите этот плоский хеш в древовидную структуру, см. Этот ответ для другого примера кода , он здесь же здесь:

 // build tree from hash $tree = array(); foreach($hash as $id => &$node) { if ($parent = $node['object']->top_id) $hash[$parent]['children'][] =& $node; else $tree[] =& $node; } unset($node, $hash); 

Наконец, вы можете вывести эту древовидную структуру как HTML. Это можно сделать либо с помощью стека, либо с помощью рекурсивного. Это один вариант с рекурсией:

 // render tree function render_tree($tree) { echo '<ul>', "\n"; foreach($tree as $node) { render_node($node); } echo '</ul>'; } // render tree node function render_node($node, $level = 0) { $inset = str_repeat(' ', $level) . ' '; echo $inset, '<li>', $node['object']->name; if (isset($node['children'])) { echo "\n", $inset, ' <ul>', "\n"; foreach($node['children'] as $node) { render_node($node, $level+1); } echo $inset, ' </ul>', "\n", $inset; } echo '</li>', "\n"; } // output render_tree($tree); 

Вывод:

 <ul> <li>Cat 1</li> <li>Cat 2 <ul> <li>Subcat 1</li> <li>Subcat 2 <ul> <li>Subcat 4</li> </ul> </li> </ul> </li> <li>Cat 3 <ul> <li>Subcat 3</li> </ul> </li> </ul> 

Полный код Пример + HTML-демо .