PHP: Построение древовидных данных в PHP
Недавно, возникла потребность сделать древовидный, порядковый список категорий, в одном из проектов.
2 главных условий, которые преследовал: 1) в html должны наглядно показываться родительские элементы и их «дети»; 2) для всей операции 1 SQL запрос.
SQL-структура была такая:
+------------+--------------+------+-----+---------+----------------+ | FIELD | Type | NULL | KEY | DEFAULT | Extra +------------+--------------+------+-----+---------+----------------+ | categoryID | int(3) | NO | PRI | NULL | AUTO_INCREMENT | | parent | int(3) | NO | | 0 | | | name | varchar(255) | NO | | NULL | | | slug | varchar(255) | NO | | NULL | | | pic | varchar(255) | YES | | NULL | | +------------+--------------+------+-----+---------+----------------+ 5 rows IN SET (0.03 sec)
После запроса в БД массив получился такой.
Array ( [0] => Array ( [categoryID] => 1 [parent] => 0 [name] => Фильмы [slug] => films [pic] => ) [1] => Array ( [categoryID] => 2 [parent] => 0 [name] => Музыка [slug] => music [pic] => ) [...] )
Для удобной работы я сгруппировал массив по categoryID, заменив его ключи на этот идентификатор.
foreach ($data as $v) $array[$v['categoryID']] = $v;
А вот и сама функция, которая пишет в глобальный массив $g_data результат своей рекурсивной работы.
function tree(&$data, $node_id, $lvl = 0) { switch ($lvl) { // для каждой категории может быть действие (напр. присвоить id) case 0: $html = '<option style="font-weight:bolder;" disabled>- КОРЕНЬ -</strong>'."\n"; break; default: // str_repeat делает отступ слева, в зависимости от уровня кат-ии. Это наглядно показывает юзеру родителя категории и его дочерний элемент. А если кат-я самая "верхняя", она выделяется стилем font-weight:bold $html = '<option '.($data[$node_id]['parent']==0?'style="font-weight:bold;':'').' value="'.$data[$node_id]['categoryID'].'">'.str_repeat(' ', $lvl) . $data[$node_id]['name'].'</option>'."\n"; } $this->g_data['tree'] .= $html; // рекурсия foreach ($data as $row) if ($row['parent'] == $node_id) $this->tree($data, $row['categoryID'], $lvl + 1); }
Остаётся только запустить процесс.
tree($array, 0);
Уважаемый автор – не могли бы Вы пояснить некоторые моменты Вашего кода?
Конечно.