php. Вложенные категории


Пример реализации вложенных категорий. По данному примеру можно аналогично реализовать вложенные комментарии.

Для начала возьмем переменную, которая будет содержать массив со списком категорий:
$data = [
    ['id'=>1, 'title'=>'Программирование'],
    ['id'=>2, 'title'=>'Php'],
    ['id'=>3, 'title'=>'Js'],
    ['id'=>4, 'title'=>'Python'],
    ['id'=>5, 'title'=>'Frontend'],
    ['id'=>6, 'title'=>'Backend'],
    ['id'=>7, 'title'=>'Компьютеры'],
    ['id'=>8, 'title'=>'Железо'],
    ['id'=>9, 'title'=>'Видеокарты'],
    ['id'=>10, 'title'=>'Процессор'],
    ['id'=>11, 'title'=>'Материнская плата'],
    ['id'=>12, 'title'=>'Комплектующие'],
    ['id'=>13, 'title'=>'Оперативная память'],
    ['id'=>14, 'title'=>'Мышь'],
    ['id'=>15, 'title'=>'Клавиатура'],
    ['id'=>16, 'title'=>'Монитор'],
    ['id'=>17, 'title'=>'Жесткий диск'],
    ['id'=>18, 'title'=>'Геймпад'],
    ['id'=>19, 'title'=>'Html'],
];

Данные категории совершенно не имеют никакой вложенности. Для того, чтобы создать какое-то соотношение, необходимо добавить колонку к каждой из категорий.
Назовем эту колонку 'parent_id'. Будет считать, что самые главные категории не имеют предков и их 'parent_id', будет равен null.
К примеру категория 'Программирование' будет самой главной и не должна меть предка, но у нее есть дочерняя категория 'Frontend'. По этому 'parent_id' у категории 'Программирование' будет равен null, а категория 'Frontend' будет иметь 'parent_id' равный 1. Так как категория 'Frontend', является дочерней категорией 'Программированию'.

Представим, что наши категории обросли вложенностью и у них определен parent_id:
$data = [
    ['id'=>1, 'title'=>'Программирование', 'parent_id' => null],
    ['id'=>2, 'title'=>'Php', 'parent_id' => 6],
    ['id'=>3, 'title'=>'Js', 'parent_id' => 5],
    ['id'=>4, 'title'=>'Python', 'parent_id' => 6],
    ['id'=>5, 'title'=>'Frontend', 'parent_id' => 1],
    ['id'=>6, 'title'=>'Backend', 'parent_id' => 1],
    ['id'=>7, 'title'=>'Компьютеры', 'parent_id' => null],
    ['id'=>8, 'title'=>'Железо', 'parent_id' => 7],
    ['id'=>9, 'title'=>'Видеокарты', 'parent_id' => 8],
    ['id'=>10, 'title'=>'Процессор', 'parent_id' => 8],
    ['id'=>11, 'title'=>'Материнская плата', 'parent_id' => 8],
    ['id'=>12, 'title'=>'Комплектующие', 'parent_id' => 7],
    ['id'=>13, 'title'=>'Оперативная память', 'parent_id' => 8],
    ['id'=>14, 'title'=>'Мышь', 'parent_id' => 12],
    ['id'=>15, 'title'=>'Клавиатура', 'parent_id' => 12],
    ['id'=>16, 'title'=>'Монитор', 'parent_id' => 12],
    ['id'=>17, 'title'=>'Жесткий диск', 'parent_id' => 8],
    ['id'=>18, 'title'=>'Геймпад', 'parent_id' => 12],
    ['id'=>19, 'title'=>'Html', 'parent_id' => 5],
];

Рассмотрим две функции для распределения категорий по вложенности:

Функция build_tree находит самых первых предков и с помощью функции prepare_children рекурсивно ищет все дочерние категории, относительно ее предыдущего предка.
Выполним функцию build_tree($data) и распечатаем результат:
print_r(build_tree($data));

Результат:

Мы получили массив со вложенными категориями, относительно их предков.
И теперь распечатаем названия категорий, полученные в результате выполнения функции build_tree.
Для этого воспользуемся функцией execute:
/**
 * Печать всех элементов массива в порядке вложенности
 *
 * @param $data - Массив вложенных категорий
 * @param int $level - Уровень вложенности
 */
function execute($data, $level = 0) {
    $level++;
    foreach ($data as $datum) {
        echo str_repeat("&nbsp;", $level - 1) . $datum['title'] . "<br />";
        execute($datum['children'], $level);
    }
}

Данная функция распечатает названия категорий в порядке вложенности. Вложенность будет определяться с помощью знака пробел.
С каждым уровнем вложенности добавляется пробел.
Выполняем функцию execute:
execute(build_tree($data));

Результат выполнения функции execute:
Программирование
 Frontend
  Js
  Html
 Backend
  Php
  Python
Компьютеры
 Железо
  Видеокарты
  Процессор
  Материнская плата
  Оперативная память
  Жесткий диск
 Комплектующие
  Мышь
  Клавиатура
  Монитор
  Геймпад


Данные функции распределили все категории по уровням вложенности.
По аналогичной схеме можно определить степень вложенности комментариев.
При разработке вложенных категорий, использовались встроенные в язык PHP функции:
array_filter(), array_values(), str_repeat().

Весь пример кода:

В самом начале примера я использовал строку:
header("Content-Type: text/html; charset=UTF-8");

Для поддержки русского языка на PHP с помощью кодировки UTF-8.
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.