Welcome to a quick tutorial on how to create a dynamic navigation menu with PHP and MySQL. So you are looking for ways to dynamically generate a menu, and not have to update the HTML every time?
We can create a simple dynamic navigation menu with PHP MySQL in just a few steps:
Create a database table to store the menu items.
Create a PHP script to fetch the menu items from the database.
Finally, draw the menu in HTML.
But just how is this done? Let us walk through an example in this guide – Read on!
TLDR – QUICK SLIDES
TABLE OF CONTENTS
DYNAMIC MENU IN PHP MYSQL
All right, let us now get into the example of creating a dynamic menu with PHP and MYSQL.
STEP 1) MENU DATABASE TABLE
1A) MENU ITEMS TABLE
CREATE TABLE `menu_items` ( `item_id` bigint(20) NOT NULL, `parent_id` bigint(20) NOT NULL DEFAULT 0, `item_text` varchar(255) NOT NULL, `item_link` varchar(255) NOT NULL, `item_target` varchar(255) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ALTER TABLE `menu_items` ADD PRIMARY KEY (`item_id`), ADD KEY (`parent_id`); ALTER TABLE `menu_items` MODIFY `item_id` bigint(20) NOT NULL AUTO_INCREMENT;
These should be pretty self-explanatory. The first level items are home, blog, reviews, and shop. Only “blog” has second-level items – How to, technology, and hacks. Of course, feel free to nest deeper, for example, (8, 7, ‘Windows Hacks’, ‘blog/hacks/windows/’, NULL) . But I will advise against that – The design and HTML become very difficult with deeply nested items.
PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]); // (B) DRILL DOWN GET MENU ITEMS // ARRANGE BY [PARENT ID] => [MENU ITEMS] $menu = []; $next = [0]; while (true) < $stmt = $pdo->prepare(sprintf( "SELECT * FROM `menu_items` WHERE `parent_id` IN (%s)", implode(",", $next) )); $stmt->execute(); $next = []; while ($r = $stmt->fetch()) < if (!isset($menu[$r["parent_id"]])) < $menu[$r["parent_id"]] = []; >$menu[$r["parent_id"]][$r["item_id"]] = $r; $next[] = $r["item_id"]; > if (count($next) == 0) < break; >> // (C) CLOSE DATABASE CONNECTION $stmt = null; $pdo = null;
Connect to the database. Remember to change the settings to your own.
Use a while loop to automatically drill down to get the menu items. The menu items are in the arrangement of $menu[PARENT ID][ITEM ID] = MENU ITEM .
Close the database connection.
I can hear angry trolls screaming “so stupid and dangerous to use an infinite while loop”. I agree, the more deeply nested the menu is, the slower and more complex this becomes. There is also a risk of getting into an infinite loop.
But this is also one of the better ways to satisfy everyone who wants to do deeply nested menus. There is no perfect system, I cannot please everyone – So feel free to change this part to a recursive function if you are not happy with it.
STEP 3) DRAW HTML MENU
else < draw($i); >> ?>
Lastly, we just build the HTML menu. Take note, this will only go 2 levels deep. I will not go into how the CSS drop-down menu works, since I literally covered it in another tutorial – Links below if you are interested.
EXTRA) A SMARTER DYNAMIC MENU – SAVE IT!
%s", $i["item_target"]!="" ? "target='". $i["item_target"] ."' " : "" , $i["item_link"], $i["item_text"] ); > // (C) WRITE HTML MENU TO FILE ob_start(); foreach ($menu[0] as $id=>$i) < // (C1) WITH SUB-ITEMS if (isset($menu[$id])) < ?>
$c) < draw($c); >?>
else < draw($i); >> // (C3) OB TO MENU.HTML file_put_contents("menu.html", str_replace(["\r", "\n"], "", ob_get_contents())); ob_end_flush();
The above example works, and it is probably how almost every tutorial on the Internet preaches too. But consider the fact that the dynamic menu loads off the database on every user visit, and it is not the best for performance. So here’s a small trick – Directly generate an HTML file of the menu, it’s way faster to load static HTML.
DOWNLOAD & NOTES
Here is the download link to the example code, so you don’t have to copy-paste everything.
SUPPORT
600+ free tutorials & projects on Code Boxx and still growing. I insist on not turning Code Boxx into a «paid scripts and courses» business, so every little bit of support helps.
EXAMPLE CODE DOWNLOAD
Click here for the source code on GitHub gist, just click on “download zip” or do a git clone. I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
EXTRA BITS & LINKS
That’s it for the dynamic menu, and here are some small extras that you may find useful.
I HAVE MULTIPLE MENUS!
Simply add another menu_id to the table. For example, we can set 1 for the main menu, 2 for sidebar, and 3 for footer.
Modify the SQL – SELECT * FROM `menu_items` WHERE `menu_id`=X AND `parent_id`.
Yep, will be a good idea to package the entire 2-menu.php into a library function.
LINKS & REFERENCES
TUTORIAL VIDEO
INFOGRAPHICS CHEAT SHEET
THE END
Thank you for reading, and we have come to the end of this tutorial. I hope that it has helped you to create a better menu for your website. If you have anything to share with this guide, please feel free to comment below. Good luck and happy coding!
14 thoughts on “3 Steps Simple Dynamic Menu With PHP MYSQL”
Amazing that I have been studying this code for several days and when I went back to your explanation this morning, the download file was updated. I created an empty file named menu.html and the save function works but it only saves the top-level menu links, without the surrounding nav tags – but no child items. For a one-level menu this is perfect, you could put the nav tags in the container document itself. I might even try and create a form to help with creating and editing the database rows – a sort of menu-builder for my app. Thank you for sharing your knowledge and code!
Hi, this seems to be a very promising solution. Thanks so much. I downloaded your files and tried it. Unfortunately I get this:
Undefined offset: 0 in php-mysql-menu/3a-demo.php on line 19 Invalid argument supplied for foreach() in 3a-demo.php on line 19
I also tried a var_dump on $menu which returns array(0) <> Any idea, what is wrong here?
Tutorial updated – A small fix. The parent ID for first-level items should be 0 , not NULL .
В этой статье я покажу, как можно создавать многоуровневое меню на PHP и MySQL. Безусловно, вариантов его создания можно придумать много, но, судя по количеству Ваших вопросов на эту тему, Вам нужен пример. И его я приведу в этой статье. Сразу отмечу, что данная статья имеет смысл только для тех, кто знает PHP и умеет работать с MySQL. Всем остальным сначала надо пройти этот курс, либо прочитать какие-нибудь книги по PHP и MySQL.
Для начала создадим таблицу в базе данных со следующими полями:
id — уникальный идентификатор.
title — анкор ссылки в меню.
link — адрес, на который будет вести пункт меню.
parent_id — родительский ID. Если родительского пункта нет, то здесь будет NULL (либо можно ещё 0 поставить).
С таблицей разобрались, теперь пришло время PHP-кода. Полный PHP-код приведён ниже:
«; // Начинаем внутренний список, если дочерних элементов ещё не было $ul = true; // Устанавливаем флаг > echo printItem($items[$key], $items, $childrens); // Рекурсивно выводим все дочерние элементы > echo «»; > ?>
Меню
foreach ($items as $item) if (!$item[«parent_id»]) echo printItem($item, $items, $childrens); // Выводим все элементы верхнего уровня > ?>
Этот код полностью рабочий, однако, Вы должны понимать, что так никто не пишет (в частности, вывод через echoHTML-тегов). И Ваша задача взять алгоритм из этого кода, но не сам код. А дальше этот алгоритм подключить к своему движку. Я постарался тщательно прокомментировать код вывода многоуровневого меню на PHP и MySQL, но, безусловно, он не самый прозрачный и требует уже неплохих начальных знаний. Если Вы ещё плохо знаете PHP и MySQL, то сначала настоятельно рекомендую пройти этот курс. После прохождения данного курса Вы сможете самостоятельно писать подобные скрипты и даже намного сложнее.
Создано 03.02.2014 13:15:22
Михаил Русаков
Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!
Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov. Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.
Если Вы не хотите пропустить новые материалы на сайте, то Вы можете подписаться на обновления: Подписаться на обновления
Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.
Порекомендуйте эту статью друзьям:
Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):
Кнопка: Она выглядит вот так:
Текстовая ссылка: Она выглядит вот так: Как создать свой сайт
BB-код ссылки для форумов (например, можете поставить её в подписи):
Комментарии ( 3 ):
Спасибо за статью. Сейчас делаю новый сайт и там буду использовать этот вид меню.
Присоединяюсь к благодарностям. Миша, а как бы лучше управлять очередностью пунктов меню? Например, в Друпале у каждого элемента меню есть «вес», чем он меньше – тем ссылка выше (раньше). А в панели управления они просто перетягиваются. Ну и «Сохранить» – запись в базу данных – вот здесь я что-то не соображу никак. Если решишься сделать такой урок, будет просто здорово!
Здравствуйте Михаил! Не смогли бы Вы помочь разобраться с методом Tommy Lacroix tree? Если сможете, объясните по-подробнее пожалуйста, как метод перебирает массив? Описания в интернете вообще нет, кроме того, что так можно выводить дерево меню. Такое ощущение, что никто не знает, как она работает. Прочитал, и не один раз, как работают жёсткие ссылки — тоже минимум информации с парой примеров, скопированной с другого такого же сайта.
Для добавления комментариев надо войти в систему. Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.