Как вывести всех родителей у подкатегории до главной категории?

Добрый день.
Имеются категории и подкатегории, вложенность может быть до 4 уровня подкатегории.
Необходимо отобразить на странице подкатегории хлебные крошки, чтобы по нажатию на любого предка переходить на его страницу.
Известен id текущей подкатегории $subcategory_id = 4, и по ней необходимо узнать только её предков, вплоть до родительской у которой parent_id = 0.
Как устроена БД:

61304ecb1c42b521638545.png
Как я думаю:
- надо сформировать массив со всеми предшествующими подкатегориями и основной категории
- вывести этот массив в таком виде, т.е. от главного родителя до текущей подкатегории

613049a056da7080353562.png
Что сделано:
Попытался сделать функцию для формирования массива, но выдаёт ошибку
"Uncaught TypeError: Cannot access offset of type string on string" на строке " $sub_array['text'] = $row['title'];"

Как я думаю, мне нужно положить в массив "название" и "id" каждой подкатегории и основной категории.
Далее использовать рекурсию, чтобы обработать любое кол-во вложенности.

function get_node_data($subcategory_id)
{
    global $connection;
    $query = "SELECT * FROM category WHERE id = $subcategory_id";
    $res = mysqli_query($connection, $query);
    $result = mysqli_fetch_assoc($res);
            $output = array();
            foreach ($result as $row) {
                $sub_array = array();
                $sub_array['title'] = $row['title'];
                $sub_array['id'] = $row['id'];
                $sub_array['nodes'] = array_values(get_node_data($row['parent_id']));
                $output[] = $sub_array;
            }
            return $output;
}


Вот часть кода, куда необходимо всё выводить
<ul class="breadcrumb">
        <li class="breadcrumb-item"><a href="<?= PATH ?>">Главная</a></li>
       <li class="breadcrumb-item">Категория</li>
 </ul>


Собственно просьба помочь разобраться и подправить код, что делаю не так или не правильно мыслю?
  • Вопрос задан
  • 350 просмотров
Решения вопроса 1
@Akina
Сетевой и системный админ, SQL-программист.
WITH RECURSIVE
cte AS ( SELECT *, 1 level
         FROM category 
         WHERE id = $category_id
         UNION ALL
         SELECT cat.*, cte.level + 1
         FROM category cat
         JOIN cte ON cat.id = cte.parent_id )
SELECT *
FROM cte
ORDER BY level;

Для древних версий:
SELECT CONCAT_WS('=>', c1.id, c2.id, c3.id, c4.id, c5.id) path
FROM category c1
LEFT JOIN category c2 ON c1.parent_id = c2.id
LEFT JOIN category c3 ON c2.parent_id = c3.id
LEFT JOIN category c4 ON c3.parent_id = c4.id
LEFT JOIN category c5 ON c4.parent_id = c5.id
WHERE c1.id = $category_id

Ну соответственно подрихтовать до нужного вида выходного набора.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
В MySQL 8 решается одним запросом:
WITH RECURSIVE `cte` (`id`, `parent_id`, `title`, `n`) AS (
  SELECT `id`, `parent_id`, `title`, 0
    FROM `table`
    WHERE `id` = :categoryId
  UNION
  SELECT `t`.`id`, `t`.`parent_id`, `t`.`title`, `n`+1
    FROM `cte`
    JOIN `table` AS `t` ON `t`.`id` = `cte`.`parent_id`
)
SELECT `id`, `title`
  FROM `cte`
  ORDER BY `n` DESC
Остаётся только выбрать все строки из ответа и вывести их в цикле.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы