PHP / MySQL - построение иерархии навигационного меню

StackOverflow https://stackoverflow.com/questions/477793

Вопрос

Таким образом, итоговое меню будет выглядеть примерно так:

Item B
    Item B-1
        Item B-1-2
        Item B-1-1
Item A
    SubItem A-1
    SubItem A-2
Item C

На основе следующих записей базы данных:

id        menu_title          parent_menu_id    menu_level    weight
1         Item A                0                           1                     1
2         Item B                0                           1                     0
3         Item C                0                           1                     2
4         SubItem A-2       1                           2                     1
5         Item B-1             2                           2                     0
6         Item B-1-1          5                           3                     1
7         SubItem A-1       1                           2                     0
8         Item B-1-2          5                           3                     0

Как бы я поступил с отображением? Я предполагаю, что это потребует хранения всех элементов в многомерном массиве, а затем каким-то образом перебирать его...

Это было полезно?

Решение

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

Рассматривали ли вы другие способы хранения иерархии? Ознакомьтесь с измененным обходом предварительного заказа - вот хорошая статья на основе PHP об этом ,

Другие советы

Иерархические данные несколько раздражают в базе данных отношений (исключая Oracle, в которой есть операторы в START WITH/CONNECT BY чтобы справиться с этим).В основном существуют две модели:список смежности и вложенные множества.

Вы выбрали наборы смежности, что я обычно и делаю.Ее гораздо проще изменить, чем модель вложенного набора, хотя модель вложенного набора может быть получена в правильном порядке с помощью одного запроса.Списков смежности быть не может.Вам нужно будет создать промежуточную структуру данных (дерево), а затем преобразовать ее в список.

Что бы я сделал (и фактически сделал недавно), так это:

  • выберите все содержимое меню в одном запросе, упорядоченном по родительскому идентификатору;
  • Постройте дерево структуры меню, используя ассоциативные массивы или классы / объекты;
  • Пройдитесь по этому дереву, чтобы создать вложенные неупорядоченные списки;и
  • Используйте подключаемый модуль jQuery, например Суперфиш чтобы превратить этот список в меню.

Вы строите что-то вроде этого:

$menu = array(
  array(
    'name' => 'Home',
    'url' => '/home',
  ),
  array(
    'name' => 'Account',
    'url' => '/account',
    'children' => array(
      'name' => 'Profile',
      'url' => '/account/profile',
    ),
  ),
  // etc
);

и преобразуйте это в это:

<ul class="menu">;
  <li><a href="/">Home</a></li>
  <li><a href="/account">Account Services</a>
    <ul>
      <li><a href="/account/profile">Profile</a></li>
...

PHP для генерации массива menu на основе достаточно прост, но немного сложен в решении.Вы используете рекурсивную функцию обхода дерева, которая создает разметку вложенного списка HTML, но оставим ее реализацию в качестве упражнения для читателя.:)

Способ хранения иерархических данных не так эффективен, как хотелось бы. Я прочитал статью Управление иерархическими данными в MySQL несколько лет назад и с тех пор нашел его как лучшее решение для управления данными на основе иерархии в SQL. Следующим лучшим преимуществом является то, что я считаю, что вы можете получить все дерево одним запросом.

Я только что опубликовал в аналогичном вопросе свой собственный подход к преобразованию иерархических данных MySQL (список смежности) в меню (HTML)

Это так и есть нет используйте рекурсию.И для этого требуется одиночный запрос к базе данных.

Читайте больше по адресу

https://stackoverflow.com/questions/2871861#3368622

Спасибо.

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

Item B
    Item B-1
        Item B-1-2
        Item B-1-1
Item A
    SubItem A-1
    SubItem A-2
Item C

станет

1 Item B
  1.1 Item B1
    1.1.1 Item B11
    1.1.2 Item B12
2 Item A
  2.1 Item A1
  2.2 Item B2
3 Item C

Цифра перед каждым элементом может быть сохранена в поле и проанализирована на основе длины (представляющей глубину ее расположения), чтобы рассказать вам все, что вам нужно знать о том, куда она идет.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top