Недавно, возникла потребность сделать древовидный, порядковый список категорий, в одном из проектов. 2 главных условия, которые соблюдал: 1) в html должны наглядно показываться родительские элементы и их "дети"; 2) для всей операции 1 SQL запрос. SQL-структура была такая:
  1. ---------------------------------------------------------------------------------
  2. | FIELD          | Type             | NULL   | KEY | DEFAULT   | Extra
  3.  ---------------------------------------------------------------------------------
  4. | categoryID     | int(3)           | NO    | PRI   | NULL     | AUTO_INCREMENT  |
  5. | parent         | int(3)           | NO    |       | 0        |                 |
  6. | name           | varchar(255)     | NO    |       | NULL     |                 |
  7. | slug           | varchar(255)     | NO    |       | NULL     |                 |
  8. | pic            | varchar(255)     | YES   |       | NULL     |                 |
  9.  ---------------------------------------------------------------------------------
  10. 5 rows IN SET (0.03 sec)
После запроса в БД массив получился такой.
  1. Array
  2. (
  3.     [0] => Array
  4.         (
  5.             [categoryID] => 1
  6.             [parent] => 0
  7.             [name] => Фильмы
  8.             [slug] => films
  9.             [pic] =>
  10.         )
  11.  
  12.     [1] => Array
  13.         (
  14.             [categoryID] => 2
  15.             [parent] => 0
  16.             [name] => Музыка
  17.             [slug] => music
  18.             [pic] =>
  19.         )
  20. [...]
  21. )
Для удобной работы я сгруппировал массив по categoryID, заменив его ключи на этот идентификатор.
  1. foreach ($data AS $v)
  2. $array[$v['categoryID']] = $v;
А вот и сама функция, которая пишет в глобальный массив $g_data результат своей рекурсивной работы.
  1. FUNCTION tree (&$data, $node_id, $lvl = 0)
  2. {
  3.    switch ($lvl)
  4.    {
  5.       // для каждой категории может быть действие (напр. присвоить id)
  6.         case 0:
  7.         $html = '<option style="font-weight:bolder;" disabled>- КОРЕНЬ -</strong>'."\n";
  8.         break;
  9.         DEFAULT:
  10.         /* str_repeat делает отступ слева, в зависимости от уровня кат-ии. Это наглядно показывает юзеру родителя категории и его дочерний элемент. А если кат-я самая "верхняя", она выделяется стилем font-weight:bold */
  11.         $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";
  12.     }
  13.   $this->g_data['tree'] .= $html;
  14.        
  15.    // рекурсия
  16.    foreach ($data AS $row)
  17.       IF ($row['parent'] == $node_id)
  18.          $this->tree($data, $row['categoryID'], $lvl   1);
  19. }
Остаётся только запустить процесс.
tree($array, 0);


Статью пока никто не комментировал. Ваш комментарий может стать первым.

Войдите или зарегистрируйтесь, чтобы написать комментарий.