Компьютеры
и программирование

Многоуровневое меню сайта с развёрнутыми текущими уровнями

Многоуровневое меню может потребоваться на содержащих большое количество информации сайтах самых разных назначений: сайтах-каталогах продукции или услуг, интернет-магазинах, каталогах статей или информационных сайтах. Нередко даже имеющие опыт в нескольких годах веб-мастера теряются перед проблемой: как сделать, чтобы при открытии некоторого пункта каталога развёрнутыми были все пункты предыдущих уровней, являющимися над-уровнями открытого некоторого пункта.

Так, например, есть пункт первого уровня - "Техника", пункт второго уровня - "Техника для дома" и пункт третьего уровня - "Пылесосы". Требуется достичь, чтобы при открытии (активизации) пункта "Пылесосы" был развёрнут не только пункт второго уровня "Техника для дома", но и остальные пункты второго уровня, например, "Товары для офиса", а также, чтобы развёрнутым оставался не только пункт "Пылесосы", но и остальные пункты третьего уровня, относящиеся к "Технике для дома".

Иной раз ищут решение задачи многоуровневого меню на javascript и находят его, но нелишне помнить, что большое количество javascript-кода отрицательно влияет на скорость загрузки страниц сайта. Здесь предлагается решение многоуровнего меню с развёрнутыми текущими уровнями, реализуемое только средствами PHP и математической логики.

О логических операциях с логическими же функциями можно узнать из материала "Булева алгебра (алгебра логики)".

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

Первое, что необходимо сделать, это создать в базе данных сайта таблицу categories.

Код PHP/MySQL

CREATE TABLE IF NOT EXISTS `categories` ( `cat_id` int(4) NOT NULL AUTO_INCREMENT, `parent_id` int(4) DEFAULT NULL, `cat_name` varchar(50) NOT NULL, PRIMARY KEY (`cat_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0 AUTO_INCREMENT=1 ;

Важно иметь в виду, что такая таблица позволяет организовать многоуровневое меню с неограниченным числом уровней: каждый пункт меню, имеющий идентификатор, может иметь сколь угодно "потомков", каждый из которых также может иметь "потомков". Самый первый уровень имеет значение поля parent_id равное нулю.

Далее, в самой верхней части файла, который отвечает за вывод всех уровней нашего многоуровневого меню, например, файла страниц каталога cat.php, следует разместить код, в котором переменным, являющимся частью адреса текущей страницы сайта, присваиваются значения, передаваемые методом GET.

Код PHP

<?php if(isset($_GET['cat_id'])) {$cat_id = $_GET['cat_id'];} if(isset($_GET['hid'])) {$hid = $_GET['hid'];} if(isset($_GET['gid'])) {$gid = $_GET['gid'];} ?>

Конструкции, приведённые в коде выше, являются предметом вопроса в Тесте по теме Программирование PHP/MySQL.

И, наконец, самое интересное - логика организации многоуровневого меню, в нашем случае - трёхуровневого. С первым уровнем, надо полагать, всё сразу понятно: из базы данных выбираются те пункты меню, поле parent_id которых имеет значение 0. Второй уровень несколько посложней: выбираются те пункты меню, которые соответствуют активному состоянию одного из пунктов меню первого уровня. Аналогично работает и третий уровень: выбираются те пункты меню, которые соответствуют активному состоянию одного из пунктов меню второго уровня.

Код PHP

<?php $mybasecat = mysql_query("SELECT `cat_id`,`cat_name`,`cat_pic` FROM `categories` WHERE `parent_id`='0'",$db) or die(mysql_error()); if (mysql_num_rows($mybasecat) > 0) { $myrowcat = mysql_fetch_array($mybasecat); do { echo '<li><a href="cat.php?gid='.$myrowcat['cat_id'].'&cat_id='.$myrowcat['cat_id'].'">'.$myrowcat['cat_name_ru'].'</a></li>'; $mybasecat1 = mysql_query("SELECT `cat_id`,`cat_name` FROM `categories` WHERE (`parent_id`='{$gid}' AND `parent_id`='{$myrowcat['cat_id']}') ORDER BY `cat_id` DESC",$db) or die(mysql_error()); $myrowcat1 = mysql_fetch_array($mybasecat1); if (mysql_num_rows($mybasecat1) > 0) { echo '<ul style="margin: 0px 0px 0px 20px;">'; do { echo '<li style="height: 10px;"><a style="font-size: 11px;" href="cat.php?gid='.$gid.'&cat_id='.$myrowcat1['cat_id'].'">'.$myrowcat1['cat_name'].'</a></li>'; $mybasecat2 = mysql_query("SELECT `cat_id`,`cat_name` FROM `categories` WHERE (`parent_id`='{$cat_id}' AND `parent_id`='{$myrowcat1['cat_id']}') OR (`parent_id`='{$hid}' AND `parent_id`='{$myrowcat1['cat_id']}') ORDER BY `cat_id` DESC",$db) or die(mysql_error()); $myrowcat2 = mysql_fetch_array($mybasecat2); if (mysql_num_rows($mybasecat2) > 0) { echo '<ul style="margin: 0px 0px 0px 40px;">'; do { echo '<li style="height: 10px;"><a style="font-size: 11px;" href="cat.php?gid='.$gid.'&hid='.$myrowcat1['cat_id'].'&cat_id='.$myrowcat2['cat_id'].'">'.$myrowcat2['cat_name'].'</a></li>'; } while($myrowcat2 = mysql_fetch_array($mybasecat2)); echo '</ul>'; } } while($myrowcat1 = mysql_fetch_array($mybasecat1)); echo '<li style="height: 2px;"></li> </ul>'; } } while($myrowcat = mysql_fetch_array($mybasecat)); } else { echo "Нет категорий"; } ?>

При этом все уровни, по которым проходит путь к активному пункту меню последнего уровня, остаются открытыми. Это достигается передачей методом GET частей адреса текущей страницы, формируемых из идентификаторов категорий.

В реализации многоуровневого меню широко задействована алгебра логики. Научиться комбинировать различные условия для выборок из базы данных можно на материале "Булева алгебра (алгебра логики)".

А об операциях для манипулирования данными из баз данных - материал "Реляционная алгебра"

Поделиться с друзьями