Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 21.12.2017, 00:21
Профессор
Отправить личное сообщение для DivMan Посмотреть профиль Найти все сообщения от DivMan
 
Регистрация: 08.03.2016
Сообщений: 429

трёхуровневое меню
Надо у подкатегории вывести подкатегорию.

Убил 2 дня, перепробовал всякие способы, в итоге сделал свой велосипед на костылях, рекурсией мне такое задание сделать очень сложно.

Такой код допускается на проекте? Какой способ ещё есть?

Делаю запрос

SELECT
    category.id AS catId, category.name AS catName,
    sub_category.id AS subCatId, sub_category.name AS subCatName,
    page.id AS pageId, page.name AS pageName

FROM category LEFT JOIN sub_category
ON sub_category.category_id = category.id LEFT JOIN page
ON page.sub_category_id = sub_category.id ORDER BY category.id


Мне присылается вот такой массив

$res = [
        ['catId' => 1, 'catName' => 'Программы', 'subCatId' => 1, 'subCatName' => "Антивирусы", 'pageId' => "1", 'pageName' => "Касперский"],
        ['catId' => 1, 'catName' => 'Программы', 'subCatId' => 4, 'subCatName' => "Аудио", 'pageId' => "4", 'pageName' => "VirtualDJ"],
        ['catId' => 1, 'catName' => 'Программы', 'subCatId' => 4, 'subCatName' => "Аудио", 'pageId' => "5", 'pageName' => "FL Studio"],
        ['catId' => 1, 'catName' => 'Программы', 'subCatId' => 1, 'subCatName' => "Антивирусы", 'pageId' => "6", 'pageName' => "NOD32"],
        ['catId' => 1, 'catName' => 'Программы', 'subCatId' => 2, 'subCatName' => "Запись", 'pageId' => "NULL", 'pageName' => "NULL"],
        ['catId' => 1, 'catName' => 'Программы', 'subCatId' => 3, 'subCatName' => "Интернет", 'pageId' => "NULL", 'pageName' => "NULL"],
        ['catId' => 2, 'catName' => 'Фильмы',    'subCatId' => 5, 'subCatName' => "Боевики", 'pageId' => "2", 'pageName' => "Джпеки Чан"],
        ['catId' => 2, 'catName' => 'Фильмы',    'subCatId' => 7, 'subCatName' => "Ужастики", 'pageId' => "3", 'pageName' => "Псы войны"],
        ['catId' => 2, 'catName' => 'Фильмы',    'subCatId' => 5, 'subCatName' => "Боевики", 'pageId' => "8", 'pageName' => "Американский ниндзя"],
        ['catId' => 2, 'catName' => 'Фильмы',    'subCatId' => 6, 'subCatName' => "Фантастика", 'pageId' => "NULL", 'pageName' => "NULL"],
    ];


Потом я из него делаю другой массив, который мне нужен. Вот так я его делаю

$mass = [];
foreach($res as $cat) {
    if (!array_key_exists($cat['catName'] . '|' . $cat['catId'], $mass)) {
        $mass[$cat['catName'] . '|' . $cat['catId']] = [$cat['subCatName'] . '|' . $cat['subCatId']=> [$cat['pageId']=>$cat['pageName']]];
    }

    else {
        $mass[$cat['catName']. '|' .$cat['catId']][$cat['subCatName'] . '|' .$cat['subCatId']][$cat['pageId']]=$cat['pageName'];
    }
}


После этого получился вот такой массив

Array
(
    [Программы|1] => Array
        (
            [Антивирусы|1] => Array
                (
                    [1] => Касперский
                    [6] => NOD32
                )

            [Аудио|4] => Array
                (
                    [4] => VirtualDJ
                    [5] => FL Studio
                )

            [Запись|2] => Array
                (
                    [] =>
                )

            [Интернет|3] => Array
                (
                    [] =>
                )

        )

    [Фильмы|2] => Array
        (
            [Боевики|5] => Array
                (
                    [2] => Джеки Чан
                    [8] => Американский ниндзя
                )

            [Ужастики|7] => Array
                (
                    [3] => Псы войны
                )

            [Фантастика|6] => Array
                (
                    [] =>
                )

        )

)


И потом уже, создаю списки

echo '<ul>';
foreach($mass as $key => $val) {
    $category = explode('|', $key);
    echo '<li><a href="/category/'.$category[1].'">'.$category[0].'</a>';
         foreach($val as $k => $v) {
            $subCategory = explode('|', $k);
                echo '<ul>';
                    echo '<li><a href="/sub-category/'.$subCategory[1].'">'.$subCategory[0].'</a>';
                         foreach($v as $postKey => $postVal) {
                            echo '<ul>';
                                echo '<li><a href="/post/'.$postKey.'">'.$postVal.'</a></li>';
                            echo '</ul>';
                         }
                    echo '</li>';
                echo '</ul>';
         }
    echo '</li>';
}
echo '</ul>';


Получается вот такое

Ответить с цитированием
  #2 (permalink)  
Старый 21.12.2017, 01:12
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Запоминать уровни в переменных вне цикла когда текущий не равен им, сверяя каждый последующий строить список.

$mass[$cat['catName']. '|' .$cat['catId']][$cat['subCatName'] . '|' .$cat['subCatId']] - это никуда не годится, уж тогда построить человеческий промежуточный многомерный массив.
Ответить с цитированием
  #3 (permalink)  
Старый 21.12.2017, 01:19
Профессор
Отправить личное сообщение для DivMan Посмотреть профиль Найти все сообщения от DivMan
 
Регистрация: 08.03.2016
Сообщений: 429

laimas,
По другому я не умею
Ответить с цитированием
  #4 (permalink)  
Старый 21.12.2017, 02:50
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

А $res ни о чем не говорит? )

У вас фиксированный уровень вложенности, причем каждое вложение, это отдельная таблица. Проще получить все раздельными запросами:

$level1 = SELECT * FROM category WHERE EXISTS (SELECT * FROM sub_category WHERE sub_category.category_id = category.id) ORDER BY id

$level2 = SELECT * FROM sub_category WHERE category_id IN (implode(',', array_column($level1, 'id'))) AND EXISTS (SELECT * FROM page WHERE page.sub_category_id = sub_category.id) ORDER BY sub_category_id

И из последней как и для второй по набору id из второй и непустых значений. Проходом в цикле первого уровня, получая данные из остальных уровней уровней построить список.

Это же самое можно сделать и с результатом одного запроса, если его правильно отсортировать на выходе.

Уже давно версии MySQL позволяют опускать AS, то есть просто category.id catId. И полезно давать таблицам алиас, чтобы не писать длинные портянки.

Последний раз редактировалось laimas, 21.12.2017 в 02:53.
Ответить с цитированием
  #5 (permalink)  
Старый 21.12.2017, 07:26
Профессор
Отправить личное сообщение для DivMan Посмотреть профиль Найти все сообщения от DivMan
 
Регистрация: 08.03.2016
Сообщений: 429

2 запроса это плохо
Ответить с цитированием
  #6 (permalink)  
Старый 21.12.2017, 07:37
Профессор
Отправить личное сообщение для DivMan Посмотреть профиль Найти все сообщения от DivMan
 
Регистрация: 08.03.2016
Сообщений: 429

А о чём $res должна говорить?
Ответить с цитированием
  #7 (permalink)  
Старый 21.12.2017, 10:10
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от DivMan
2 запроса это плохо
Чем? И будет не два, а три.

Сообщение от DivMan
А о чём $res должна говорить?
О том что вывод из базы не подходит под разбор.

Есть мешочек, в который насыпаны карточки со словами. Какой алгоритм действий должен быть, чтобы вынимая по одной карточке разложить их в алфавитном порядке предваряя группы слов буквой алфавита?
Ответить с цитированием
  #8 (permalink)  
Старый 21.12.2017, 21:57
Профессор
Отправить личное сообщение для DivMan Посмотреть профиль Найти все сообщения от DivMan
 
Регистрация: 08.03.2016
Сообщений: 429

бред какой-то
Ответить с цитированием
  #9 (permalink)  
Старый 22.12.2017, 03:50
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от laimas
бред какой-то
Ну тогда вам и не понять какую ошибку вы допускаете в своем запросе, надеясь его разобрать единым махом.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Замена стилей класса Павел Турченко Элементы интерфейса 9 30.10.2015 15:24
Бесконечноуровневое меню на CSS ruslan_mart Ваши сайты и скрипты 5 12.01.2015 20:59
Текуший пункт меню и разные родители Kiano Элементы интерфейса 17 08.01.2015 07:59
Выделение активных пунктов многоуровневого меню на jQuery Letto Элементы интерфейса 2 04.12.2013 15:30
Проблема с аккордионом и меню Tie ExtJS 3 01.09.2011 14:36