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