Для начала создадим таблицу в базе данных со следующими полями:

Многоуровневое меню на PHP и MySQL

Для начала создадим таблицу в базе данных со следующими полями:

  • id - уникальный идентификатор.
  • title - анкор ссылки в меню.
  • link - адрес, на который будет вести пункт меню.
  • parent_id - родительский ID. Если родительского пункта нет, то здесь будет NULL (либо можно ещё 0 поставить).

С таблицей разобрались, теперь пришло время PHP-кода. Полный PHP-код приведён ниже:

<?php
  $mysqli = new mysqli("localhost", "root", "", "db"); // Подключаемся к БД
  $result_set = $mysqli->query("SELECT * FROM `menu`"); // Делаем выборку всех записей из таблицы с меню
  $items = array(); // Массив для пунктов меню
  while (($row = $result_set->fetch_assoc()) != false) $items[$row["id"]] = $row; // Заполняем массив выборкой из БД
  $childrens = array(); // Массив для соответствий дочерних элементов их родительским
  foreach ($items as $item) {
    if ($item["parent_id"]) $childrens[$item["id"]] = $item["parent_id"]; // Заполняем массив
  }
  function printItem($item, $items, $childrens) {
    /* Выводим пункт меню */
    echo "<li>";
    echo "<a href='".$item["link"]."'>".$item["title"]."</a>";
    $ul = false; // Выводились ли дочерние элементы?
    while (true) {
      /* Бесконечный цикл, в котором мы ищем все дочерние элементы */
      $key = array_search($item["id"], $childrens); // Ищем дочерний элемент
      if (!$key) {
        /* Дочерних элементов не найдено */
        if ($ul) echo "</ul>"; // Если выводились дочерние элементы, то закрываем список
        break; // Выходим из цикла
      }
      unset($childrens[$key]); // Удаляем найденный элемент (чтобы он не выводился ещё раз)
      if (!$ul) {
        echo "<ul>"; // Начинаем внутренний список, если дочерних элементов ещё не было
        $ul = true; // Устанавливаем флаг
      }
      echo printItem($items[$key], $items, $childrens); // Рекурсивно выводим все дочерние элементы
    }
    echo "</li>";
  }
?>
<div id="menu">
  <h2>Меню</h2>
  <ul>
    <?php
      foreach ($items as $item) {
        if (!$item["parent_id"]) echo printItem($item, $items, $childrens); // Выводим все элементы верхнего уровня
      }
    ?>
  </ul>
</div>