Многоуровневое меню на PHP и MySQL
 
			В этой статье я покажу, как можно создавать многоуровневое меню на PHP и MySQL. Безусловно, вариантов его создания можно придумать много, но, судя по количеству Ваших вопросов на эту тему, Вам нужен пример. И его я приведу в этой статье. Сразу отмечу, что данная статья имеет смысл только для тех, кто знает PHP и умеет работать с MySQL. Всем остальным сначала надо пройти этот курс, либо прочитать какие-нибудь книги по 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>
	Этот код полностью рабочий, однако, Вы должны понимать, что так никто не пишет (в частности, вывод через echo HTML-тегов). И Ваша задача взять алгоритм из этого кода, но не сам код. А дальше этот алгоритм подключить к своему движку. Я постарался тщательно прокомментировать код вывода многоуровневого меню на PHP и MySQL, но, безусловно, он не самый прозрачный и требует уже неплохих начальных знаний. Если Вы ещё плохо знаете PHP и MySQL, то сначала настоятельно рекомендую пройти этот курс. После прохождения данного курса Вы сможете самостоятельно писать подобные скрипты и даже намного сложнее.
- 
					Создано 03.02.2014 13:15:22  
- 
					 Михаил Русаков Михаил Русаков
 
			 
			 
		 
				 
			 
				 
				 
				 
				
Комментарии (3):
Спасибо за статью. Сейчас делаю новый сайт и там буду использовать этот вид меню.
Ответить
Присоединяюсь к благодарностям. Миша, а как бы лучше управлять очередностью пунктов меню? Например, в Друпале у каждого элемента меню есть "вес", чем он меньше – тем ссылка выше (раньше). А в панели управления они просто перетягиваются. Ну и "Сохранить" – запись в базу данных – вот здесь я что-то не соображу никак. Если решишься сделать такой урок, будет просто здорово!
Ответить
Здравствуйте Михаил! Не смогли бы Вы помочь разобраться с методом Tommy Lacroix tree? Если сможете, объясните по-подробнее пожалуйста, как метод перебирает массив? Описания в интернете вообще нет, кроме того, что так можно выводить дерево меню. Такое ощущение, что никто не знает, как она работает. Прочитал, и не один раз, как работают жёсткие ссылки - тоже минимум информации с парой примеров, скопированной с другого такого же сайта.
Ответить
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.