За последние 24 часа нас посетили 56336 программистов и 1692 робота. Сейчас ищут 1078 программистов ...

Правильно вывести категории и товары

Тема в разделе "PHP и базы данных", создана пользователем TigerZaka, 24 окт 2014.

  1. TigerZaka

    TigerZaka Активный пользователь

    С нами с:
    16 сен 2011
    Сообщения:
    189
    Симпатии:
    1
    Всем привет!
    Есть две базы:
    категории - id, cat_name, parent_id
    товары - id, prod_name, parent_cat

    Нужно вывести в формате:
    Код (Text):
    1. кат1
    2.   тов1
    3.   тов2
    4. кат2
    5.   тов4
    6.   тов6
    Не соображу, как запрос составить, подскажите, в какую сторону смотреть
     
  2. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    две таблицы

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

    кстати
    если вы хотите вложенность категорий реализовать то рекомендую сразу на nested sets посмотреть.
     
  3. TigerZaka

    TigerZaka Активный пользователь

    С нами с:
    16 сен 2011
    Сообщения:
    189
    Симпатии:
    1
    да, конечно ))
    спасибо за наводку
     
  4. qwermus

    qwermus Новичок

    С нами с:
    27 окт 2014
    Сообщения:
    21
    Симпатии:
    0
    Я бы поступил так:
    Выбрал бы все из двух баз сразу, т.е.
    Код (Text):
    1. SELECT f.cat_name, f.parent_id, s.id, s.prod_name, s.parent_cat FROM f LEFT JOIN s ON s.parent_cat=f.id ORDER BY f.cat_name, s.prod_name
    Далее все данные сохранил бы в массив таким образом:
    Код (Text):
    1.  
    2. $array['cats'][ $row['parent_cat'] ] = $row['cat_name']; // Список категорий
    3. $array['tovs'][ $row['parent_cat'] ][] = $row; // Список товаров по категориям
    Далее этот массив можно вывести в шаблонизаторе, либо посто ниже в коде таким образом:
    Код (Text):
    1.  
    2. echo '<ul>'; // Откроем список категорий
    3. foreach ( $array['cats'] as $key=>$value ) { // Переберем категории
    4.    echo '<li>'.$value.''; // Выведем название категории
    5.    echo '<ul>'; // Откроем список товаров
    6.    foreach ( $array['tovs'][$key] as $tov ) { // Переберем товары
    7.       echo '<li>'.$tov['prod_name'].'</li>'; // Выведем название товара. Используя другие значения, можно сделать ссылку, чекбокс для формы и т.п.
    8.    }
    9.    echo '</ul></li>'; // Закроем список товаров и категорий
    10. }
    11. echo '</ul>'; // Закроем список категорий
     
  5. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    из двух таблиц. шож вы все постоянно терминологию нарушаете?

    дерево категорий-товаров как будет выглядеть в вашем решении?
     
  6. qwermus

    qwermus Новичок

    С нами с:
    27 окт 2014
    Сообщения:
    21
    Симпатии:
    0
    Конечно, Вы правильно меня поправили. Не из двух баз, а из двух таблиц. Моим клиентам чаще понятнее слово "база", чем "таблица", отсюда и привычка называть таблицы базами.
    Дерево будет выглядеть так, как просил автор. Я же код привел для примера. Вот так будет:
    Код (Text):
    1.  
    2. <ul>
    3.    <li>Категория 1<ul>
    4.       <li>Товар 1</li>
    5.       <li>Товар 2</li>
    6.       <li>Товар 3</li>
    7.    </ul></li>
    8. </ul>
    Если на jQuery дописать код, который будет по клику на "<ul><li>" открывать вложенный скрытый <ul>, то получим еще и раскрывающийся список. Точно таким же образом я делал левое меню для сайта http://точкалояльности.рф/
     
  7. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    а сразу дерево как вывести? одной итерацией и без всяких там дополнительных плагинов? автор может и просил показать одноуровневые связки категория+товар-в-категории. но в его коде есть упоминание родительской категории для категории. значит можно требовать вывести дерево категорий-подкатегорий-подподкатегорий-товаров. одна итерация, без лишних модулей. поехали.
     
  8. qwermus

    qwermus Новичок

    С нами с:
    27 окт 2014
    Сообщения:
    21
    Симпатии:
    0
    В самом начале я написал: "Я бы поступил так". Я не писал: "Единственно верный вариант - это...".
    Если взять задачу с множеством вложенных категорий, то я бы поступил так:
    начало кода такое же. Мы выбираем данные в массив. Однако массив категорий будет выглядеть не так:
    Код (Text):
    1. $array['cats'][ $row['parent_cat'] ]
    а так:
    Код (Text):
    1. $array['cats'][ $row['parent_id'] ][ $row['parent_cat'] ]
    Ну и где вывод в текст сделать это через функцию:
    Код (Text):
    1.  
    2. // Покажем товары
    3. function showtov( $parent_id ) {
    4.    global $array;
    5.    if ( sizeof( $array['tovs'][ $parent_id ] ) > 0 ) {
    6.       echo '<ul>';
    7.       foreach ( $array['tovs'][ $parent_id ] as $tov ) {
    8.          echo '<li>'.$value.'</li>';
    9.       }
    10.       echo '</ul>';
    11.    }
    12. }
    13. // Покажем вложенные категории
    14. function showcat( $parent_id ) {
    15.    global $array;
    16.    if ( sizeof( $array['cats'][ $parent_id ] ) > 0 ) {
    17.       echo '<ul>';
    18.       foreach ( $array['cats'][ $parent_id ] as $key=>$value ) {
    19.          echo '<li>'.$value;
    20.          showcat( $key );
    21.          showtov( $key );
    22.          echo '</li>';
    23.       }
    24.       echo '</ul>';
    25.    }
    26. }
    27. // Выведем на экран корневые категории
    28. showcat( 0 );
    Естественно, в данном случае использовать просто ul и li недостаточно - надо либо другие теги, либо классы добавить, чтобы разделить товары и категории визуально. Но это уже задача для конкретного сайта.
    Повторюсь - я не говорил, что это единственно верный способ решения. Если Вы имеете более элегантный вариант решения - предложите. Я с радостью и сам возьму его на вооружение
     
  9. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    вы какой-то невнимательный...
     
  10. qwermus

    qwermus Новичок

    С нами с:
    27 окт 2014
    Сообщения:
    21
    Симпатии:
    0
    Но ведь у автора таблица уже существует. Конечно, ее можно переделать, но вопрос был в том, как, используя текущую структуру, показать элементы в определенном виде. Для автора мой вариант все-же будет проще.
     
  11. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    во-первых, все же пишется не все-же, а все же.
    во-вторых, для односложных каталогов можно и ваше решение. никто не спорит. но я вот увидел у автора вложенность категорий и тут же предложил наиболее подходящую технологию для обслуживания иерархической структуры, коей и является каталог товаров.

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

    нс дает возможность построить дерево одной лишь итерацией результата одного лишь запроса к субд. никаких вложенных итераций. один простой цикл.
    нс позволяет легко выбрать путь/ветку/всё дерево.
    мы легко сможет построить такую плюшку, как хлебные крошки.
    мы легко сможем делать ссылки на товары в разных категориях.
    и нам для этого не надо будет делать стек рекурсивных вызовов showcat-showcat-showcat-showcat-showcat-showcat-showcat-showcat и так далее до фатала лимита рекурсии.

    и вам тоже рекомендую ознакомиться с вложенными множествами. удачи.
     
  12. qwermus

    qwermus Новичок

    С нами с:
    27 окт 2014
    Сообщения:
    21
    Симпатии:
    0
    Я так понял, мой ответ тут считается неправильным и его надо удалить, верно?
     
  13. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    В споре истина. Не надо ничего удалять.
     
  14. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Ваш ответ реализует не ту логику, которая нужна автору. Он отблагодарил меня за совет про вложенные множества, следовательно он как раз стремится реализовать не плоский каталог категория-товар, а нечто гибкое с лимитом уровней подчинения ограниченным собственной фантазией администратора каталога. Гибкость предложенного мною решения я привел комментарием ранее. То есть у моего решения плюсов больше, чем минусов.

    Ваш код работает либо с плоским каталогом (читаем выше про "не то, что хотят". 1-0), либо заставляет писать избыточный код для реализации подчинений. Напомню, лимит вложенности каталога будет равен лимиту рекурсии стека функций. То есть в дополнение к тому что программисту будет сложно обслуживать этот код (2-0) мы получаем еще и бомбу того что конечный пользователь рано или поздно может случайно создать слишком глубокую категорию, которая будет регулярно подкладывать статус 500 (3-0).

    Плоский каталог конечно может обработать каждый уважающий себя начинающий программист. Но засчитаем работу с плоским каталогом как плюс вашего решения. НС в данном случае конечно отсасывают накладными расходами на организацию иерархии. (3-1).

    А нет... НС дает возможность сортировать элементы в каталоге без лишних полей в базе. В том числе и для одного уровня. Таки 4-0.
    Ну конечно же это еще не всё.
    Путь(5-0)/ветка(6-0)/дерево(7-0).
    Симлинки на товары/категории - 8-0.
    Хлебные крошки - 9-0. Они конечно вытекают (высыпаются, если хотите) из функционала путь/ветка/дерево, но для их обработки не нужно лишних телодвижений.
    Вообще для готовой страницы каталога нужен один запрос и одна итерация результата. Можно 10-0? Ну пжалста-пжалста-пжалста...

    Обратите внимание на тот факт что я ни разу не назвал ваше решение "неправильным" как вы его сами обозвали. Я лишь просил показать гибкость и мощность вашего решения для сравнения с предложенным мною подходом. Вероятно, у вас еще мало опыта и вы боитесь такой технологии как вложенные множества, но поверьте мне уж лучше один раз понять как они работают, чем громоздить вот такие конструкции как вы привели.

    Опять же я не утверждаю что мое решение единственно верное в природе. Но если кто-то предложит что-то свое - я с удовольствием ознакомлюсь и приму к сведению. Вдруг оно мне чем-то будет полезно.

    Успехов.