Компьютеры        23.06.2022   

§2. Как сделать выпадающее вертикальное меню на php. Многоуровневое меню на PHP и MySQL Безбрежный menu php

Меню сайта на php, который управляется php скриптами имеет свои особенности. Это не просто абсолютные либо относительные ссылки, хотя это вполне может быть и так, а, как правило, динамически формируемые блоки ссылок боковых панелей с разделами и подразделами и блоки ссылок с самих внутренних страниц сайта. Динамически формируемое меню очень удобно, потому, как его можно вставлять в любое место сайта и, что самое важное в нужное время. Тоесть при переходе в разные разделы и подразделы можно динамически разворачивать и разные блоки меню. Причем они могут быть разные не только по содержанию, но и по форме и оформлению. В статическом сайте тоже вполне можно проделывать такие финты, но это будет стоить дополнительных файлов шаблона и еще массу всяких ухищрений. В то время, как сайт написанный на php ничего этого не требует. Шаблон останется, как и был. Всем будет управлять один или несколько простых php скриптов.

Для того, чтобы убедиться в этом, достаточно написать php скрипт для динамического формирования меню, например, первой рубрики и заставить его развернуть меню этой рубрики через уже написанный ранее скрипт . Остальные рубрики можно будет сформировать подобным образом. Причем код самого скрипта при этом мало чем практически не изменится. Меняться будет только текстовый файл, который будет определять названия ссылок и сами ссылки. Код такого скрипта приведен ниже по тексту.

// Формирователь меню
$menu = @file($rubric1_menu);
$lines = count($menu);
for ($i = 0; $i < $lines; $i++)
{
list($menu_link,$menu_name,$menu_title)=explode("::", $menu[$i]);
if($page == rub1_part1 and $i == 0) {$refcolor = "style="color:#cc0000"";}
elseif($page == rub1_part2 and $i == 1) {$refcolor = "style="color:#cc0000"";}
elseif($page == rub1_part3 and $i == 2) {$refcolor = "style="color:#cc0000"";}
else {$refcolor = "";}
$rubric1.="

  • ".$menu_name."
  • ";
    }
    ?>

    Для того, чтобы такой скрипт работал необходим текстовый файл в котором будут храниться названия ссылок меню, сами ссылки и их title. Создать такой файл несложно, достаточно выполнить из главного меню программы Dreamweaver команду File −> New, создать новый html документ, как было описано ранее, проверить и если необходимо изменить кодировку нового файла на UTF-8, а затем сохранить его под именем rubric1.dat в предварительно созданной для него папке data. Полный путь к этому файлу будет D:/Mysitephp/data/rubric1.dat. Содержимое файла, приведенное ниже, это сами ссылки, их названия и их title (подсказки). Кроме, для того, чтобы запустить данный скрипт в работу, его необходимо подключить с помощью функции include() в шаблонизаторе main.php.

    Rub1_part1::Раздел 1::Раздел 1 рубрики 1::
    rub1_part2::Раздел 2::Раздел 2 рубрики 1::
    rub1_part3::Раздел 3::Раздел 3 рубрики 1::

    Кроме этого необходимо также создать небольшой скрипт с установками, в котором будут храниться полный адрес сайта, пути к папкам страниц и мета описаний сайта, пути к файлам меню сайта и подключить его с помощью функции include() в шаблонизаторе main.php. Для этого необходимо создать новый php файл, и сохранить его под именем например setings.php в папке php. Полный путь к файлу будет D:/Mysitephp/php/setings.php, а его содержимое приведено ниже.

    # папка с html документами
    $doctemplates = "templates";
    # полный путь до директории скрипта
    $turl="http://mysitephp.ru";
    # база с данными
    $rubric1_menu = "data/rubric1.dat";
    ?>

    Как работает php скрипт формирования меню? Сначала в переменную $menu с помощью функции file() помещается содержимое текстового файла rubric1.dat. Затем функция count() подсчитывает количество строк в текстовом файле и функциями list() и explode() в цикле разворачивается само меню, где методом склеивания строк (операция точка . ) формируются стороки ссылок с их названиями и титлами, которое затем помещается в переменную $rubric1. Далее скрипт шаблонизатора, куда скрипт меню подключен функцией include() , перемещает содержимое переменной $rubric1 в нужное место сайта с помощью уже описанной ранее функции repl () .

    Такое меню пока работать не будет, поскольку в нем есть только сами ссылки со всеми необходимыми атрибутами, но нет, скрипта, который-бы обеспечил переход по этим ссылкам и открытие страниц сайта, которые будут соответствать этим ссылкам. Этим php скриптом мы займемся далее.

    Далее можно проект обновленный скриптом формирования меню. Скачать обновленный проект можно также на странице, которая откроется после оформления и активизации бесплатной подписки на панели справа. Адрес страницы необходимо сохранить. Именно на этой странице в дальнейшем будут появляться ссылки на скачивание обновлений проекта, различных полезных скриптов, программ, уроков и видеоуроков по схемотехнике, программированию и сайтостроению для новичков .

    Скачанный обновленный новыми скриптами проект php сайта теперь можно сравнить с тем, что получилось в результате выше описанных действий. Далее, дабы исключить разночтения полезно будет полностью заменить проект на скачанный, выполнить операцию , запустить сервер Denwer, набрать в окне браузера mysitephp.ru и просмотреть, что из этого получилось. В левой верхней части шаблона должно развернуться меню первого раздела, как показано на картинке ниже.

    Перейти и растаять в своей любимой социалке

    Ни один сайт не обходится без навигации или как еще называют "меню сайта". Так вот меню сайта бывает одноуровневым и многоуровневым в виде дерева. Если с одноуровневым меню особых сложностей в плане реализации не возникает, то при создании многоуровневого меню нужно хорошо подумать.

    Самое главное в этой задаче это спроектировать базу данных для нашего многоуровневого меню. Создадим таблицу Categories с тремя полями id , title , parent где:

    • ID - идентификатор
    • Title - Название меню
    • Parent - Родитель категории по умолчанию 0

    За ветвление меню отвечает поле Parent если Parent = 0 , то эта категория является родительской. Для того чтобы добавить потомков к родительской категории нужно в поле parent указать ID нужного родителя. Например:

    Таблицы с категориями

    Как видно из таблицы, у родительской категории Автомобили есть два потомка - это Мазда и Хонда связанных по полю Parent . А у категории Мотоциклы два потомка - это Кавасаки и Харлей . При этом у категории Лодки нет потомков. Надеюсь, что Вы поняли,как связать категории.

    Далее переходим от слов к практике. Создадим таблицу Categories.

    CREATE TABLE IF NOT EXISTS `categories` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `title` varchar(255) NOT NULL, `parent` int(10) unsigned NOT NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=20 ; -- -- Дамп данных таблицы `categories` -- INSERT INTO `categories` (`id`, `title`, `parent`) VALUES (1, "Автомобили", 0), (2, "Мотоциклы", 0), (3, "Мазда", 1), (4, "Хонда", 1), (5, "Кавасаки", 2), (6, "Харлей", 2), (7, "Мазда 3", 3), (8, "Мазда 6", 3), (9, "Седан", 7), (10, "Хечбэк", 7), (11, "Лодки", 0), (12, "Лифтбэк", 8), (13, "Кроссовер", 8), (14, "Белый", 13), (15, "Красный", 13), (16, "Черный", 13), (17, "Зеленый", 13), (18, "Мазда CX", 3), (19, "Мазда MX", 3);

    Алгоритм работы состоит из следующего:

    Создаем соединение с базой данных

    query("SET NAMES "utf8""); /* * Это "официальный" объектно-ориентированный способ сделать это * однако $connect_error не работал вплоть до версий PHP 5.2.9 и 5.3.0. */ if ($mysqli->connect_error) { die("Ошибка подключения (" . $mysqli->connect_errno . ") " . $mysqli->connect_error); } /* * Если нужно быть уверенным в совместимости с версиями до 5.2.9, * лучше использовать такой код */ if (mysqli_connect_error()) { die("Ошибка подключения (" . mysqli_connect_errno() . ") " . mysqli_connect_error()); }

    Пишем функцию получения данных из таблицы Categories

    //Получаем массив нашего меню из БД в виде массива function getCat($mysqli){ $sql = "SELECT * FROM `categories`"; $res = $mysqli->query($sql); //Создаем масив где ключ массива является ID меню $cat = array(); while($row = $res->fetch_assoc()){ $cat[$row["id"]] = $row; } return $cat; }

    Получаем массив вот такого вида, где ключ массива это ID категории.

    Функция построения дерева из массива от Tommy Lacroix

    //Функция построения дерева из массива от Tommy Lacroix function getTree($dataset) { $tree = array(); foreach ($dataset as $id => &$node) { //Если нет вложений if (!$node["parent"]){ $tree[$id] = &$node; }else{ //Если есть потомки то перебераем массив $dataset[$node["parent"]]["childs"][$id] = &$node; } } return $tree; }

    Получаем массив в виде дерева

    Скрипт целиком

    query("SET NAMES "utf8""); /* * Это "официальный" объектно-ориентированный способ сделать это * однако $connect_error не работал вплоть до версий PHP 5.2.9 и 5.3.0. */ if ($mysqli->connect_error) { die("Ошибка подключения (" . $mysqli->connect_errno . ") " . $mysqli->connect_error); } /* * Если нужно быть уверенным в совместимости с версиями до 5.2.9, * лучше использовать такой код */ if (mysqli_connect_error()) { die("Ошибка подключения (" . mysqli_connect_errno() . ") " . mysqli_connect_error()); } //Получаем массив нашего меню из БД в виде массива function getCat($mysqli){ $sql = "SELECT * FROM `categories`"; $res = $mysqli->query($sql); //Создаем масив где ключ массива является ID меню $cat = array(); while($row = $res->fetch_assoc()){ $cat[$row["id"]] = $row; } return $cat; } //Функция построения дерева из массива от Tommy Lacroix function getTree($dataset) { $tree = array(); foreach ($dataset as $id => &$node) { //Если нет вложений if (!$node["parent"]){ $tree[$id] = &$node; }else{ //Если есть потомки то перебераем массив $dataset[$node["parent"]]["childs"][$id] = &$node; } } return $tree; } //Получаем подготовленный массив с данными $cat = getCat($mysqli); //Создаем древовидное меню $tree = getTree($cat); //Шаблон для вывода меню в виде дерева function tplMenu($category){ $menu = "
  • ". $category["title"].""; if(isset($category["childs"])){ $menu .= "
      ". showCat($category["childs"]) ."
    "; } $menu .= "
  • "; return $menu; } /** * Рекурсивно считываем наш шаблон **/ function showCat($data){ $string = ""; foreach($data as $item){ $string .= tplMenu($item); } return $string; } //Получаем HTML разметку $cat_menu = showCat($tree); //Выводим на экран echo "
      ". $cat_menu ."
    "; ?>

    Результат работы

    Многоуровневое меню на PHP + MySQL для админки

    Если Вы хотите использовать данное меню в админке своего сайта, то нужно переписать пару функций tplMenu() , showCat() .

    ".$category["title"].""; }else{ $menu = ""; } if(isset($category["childs"])){ $i = 1; for($j = 0; $j < $i; $j++){ $str .= "→"; } $i++; $menu .= showCat($category["childs"], $str); } return $menu; } /** * Рекурсивно считываем наш шаблон **/ function showCat($data, $str){ $string = ""; $str = $str; foreach($data as $item){ $string .= tplMenu($item, $str); } return $string; } //Получаем HTML разметку $cat_menu = showCat($tree, ""); //Выводим на экран echo ""; ?>

    Результат работы

    Выбери Автомобили → Мазда →→ Мазда 3 →→→ Седан →→→ Хечбэк →→ Мазда 6 →→→ Лифтбэк →→→ Кроссовер →→→→ Белый →→→→ Красный →→→→ Черный →→→→ Зеленый →→ Мазда CX →→ Мазда MX → Хонда Мотоциклы → Кавасаки → Харлей Лодки

    В этой статье я покажу, как можно создавать многоуровневое меню на PHP и MySQL . Безусловно, вариантов его создания можно придумать много, но, судя по количеству Ваших вопросов на эту тему, Вам нужен пример. И его я приведу в этой статье. Сразу отмечу, что данная статья имеет смысл только для тех, кто знает PHP и умеет работать с MySQL . Всем остальным сначала надо пройти этот , либо прочитать какие-нибудь книги по PHP и MySQL .

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

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

    С таблицей разобрались, теперь пришло время 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 "

  • ";
    echo "".$item["title"]."";
    $ul = false; // Выводились ли дочерние элементы?
    while (true) {
    /* Бесконечный цикл, в котором мы ищем все дочерние элементы */
    $key = array_search($item["id"], $childrens); // Ищем дочерний элемент
    if (!$key) {
    /* Дочерних элементов не найдено */
    if ($ul) echo ""; // Если выводились дочерние элементы, то закрываем список
    break; // Выходим из цикла
    }
    unset($childrens[$key]); // Удаляем найденный элемент (чтобы он не выводился ещё раз)
    if (!$ul) {
    echo "
      "; // Начинаем внутренний список, если дочерних элементов ещё не было
      $ul = true; // Устанавливаем флаг
      }
      echo printItem($items[$key], $items, $childrens); // Рекурсивно выводим все дочерние элементы
      }
      echo "";
      }
      ?>

      Этот код полностью рабочий, однако, Вы должны понимать, что так никто не пишет (в частности, вывод через echo HTML-тегов ). И Ваша задача взять алгоритм из этого кода, но не сам код. А дальше этот алгоритм подключить к своему движку. Я постарался тщательно прокомментировать код вывода многоуровневого меню на PHP и MySQL , но, безусловно, он не самый прозрачный и требует уже неплохих начальных знаний. Если Вы ещё плохо знаете PHP и MySQL , то сначала настоятельно рекомендую пройти этот

      В общем случае задача формирования меню включает:

      • выделение HTML элементов для построения меню;
      • создание шаблона меню (создание шаблона компонента Меню );
      • включение функции показа меню (вызов компонента Меню ) в общем шаблоне ("прологе" и "эпилоге");
      • заполнение меню в соответствии со структурой сайта.

      Структура меню

      Любое меню на сайте строится на основе двух составляющих:

      • массива данных $aMenuLinks , определяющего состав меню, задает названия и ссылки для всех пунктов меню. Управление массивом данных осуществляется через административный интерфейс;
      • шаблона внешнего представления меню. Шаблон меню - это PHP код, определяющий внешний вид меню (шаблон компонента Меню ). Шаблон меню обрабатывает массив данных, выдавая на выходе HTML-код.

      Массив данных меню

      Данные для каждого типа меню хранятся в отдельном файле, имя которого имеет следующий формат: .<тип меню>.menu.php . Например, для хранения данных меню типа left будет использоваться файл .left.menu.php , а для хранения данных меню типа top - файл .top.menu.php .

      Меню является иерархически наследуемым. Файлы меню размещаются в папках тех разделов сайта, где требуется показ соответствующих типов меню. Если для данного раздела не создан соответствующий файл меню, система производит поиск файла в каталоге уровнем выше.

      Например, т.к. основное меню (в демо-версии продукта, это меню типа top ) должно выводиться во всех разделах, то файл данного меню помещается только в корневой каталог сайта.

      Соответственно меню второго уровня (в демо-версии продукта, это меню left ) выводится отдельно для каждого раздела сайта. Поэтому в папке каждого раздела создается свой файл для данного типа меню.

      Ещё пример : посетитель находится в разделе /ru/company/about/ . Для показа меню типа left файл меню ищется системой в следующей последовательности:

      1. /ru/company/about/.left.menu.php
      2. /ru/company/.left.menu.php
      3. /ru/.left.menu.php
      4. /.left.menu.php

      Если в одном из каталогов найдено меню, то поиск останавливается и в последующих каталогах уже не ищется.

      Система Bitrix Framework позволяет также создавать меню динамического типа Для этого требуется в компоненте Меню включить опцию Подключать файлы с именами вида.тип_меню.menu_ext.php ("USE_EXT" => "Y"), которая по умолчанию выключена. . Т.е. массив данных таких меню генерируется автоматически на основании некоторых данных, получаемых с помощью программного кода. Данный код должен храниться в папке соответствующего раздела сайта в файле с именем .<тип меню>.menu_ext.php.

      Основная задача подобных файлов - это манипуляция массивом $aMenuLinks . Данные файлы не редактируются визуально в модуле Управление структурой , поэтому они не смогут быть случайно отредактированы при визуальном редактировании меню. При создании этого файла используйте компонент Пункты меню (bitrix:menu.sections ).

      Примечание : В абзаце выше речь идёт только о дополнении созданного меню названиями разделов инфоблоков. Например, для дополнения меню названиями форумов этот вариант не годится.

      Внимание! Если в качестве пунктов меню используются разделы каталога без ЧПУ, необходимо указывать переменные в значимых переменных запроса.

      Примером такого меню может служить левое меню раздела Каталог книг , представленное в демо-версии продукта. Здесь первые два пункта меню Авторы и Рецензии созданы обычным способом, а остальные (Бизнес-литература , Детская литература и т.д.) формируются динамически.

      В данном случае в качестве пунктов меню используются названия групп каталога Книги , созданного на основе информационных блоков. Программный код, на основе которого генерируется меню, хранится в файле .left.menu_ext.php в папке /e-store/books/ .


      В файлах .<тип меню>.menu.php могут использоваться следующие стандартные переменные:

      • $sMenuTemplate - абсолютный путь к шаблону меню (данная переменная используется крайне редко);
      • $aMenuLinks - массив, каждый элемент которого описывает очередной пункт меню.

        Структура данного массива:

        Array ( => пункт меню 1 Array ( => заголовок пункта меню => ссылка на пункте меню => массив дополнительных ссылок для подсветки пункта меню: Array ( => ссылка 1 => ссылка 2 ...) => массив дополнительных переменных передаваемых в шаблон меню: Array ([имя переменной 1] => значение переменной 1 [имя переменной 2] => значение переменной 2 ...) => условие, при котором пункт меню появляется это PHP выражение, которое должно вернуть "true") => пункт меню 2 => пункт меню 3 ...)

      Примеры файлов меню

      IsAuthorized()"), Array("Журнал обучения", "gradebook.php", Array(), Array(), "\$GLOBALS["USER"]->IsAuthorized()"), Array("Анкета специалиста", "profile.php", Array(), Array(), "\$GLOBALS["USER"]->IsAuthorized()"),); ?> IncludeComponent("bitrix:menu.sections", "", Array("ID" => $_REQUEST["ELEMENT_ID"], "IBLOCK_TYPE" => "books", "IBLOCK_ID" => "30", "SECTION_URL" => "/e-store/books/index.php?SECTION_ID=#ID#", "CACHE_TIME" => "3600")); $aMenuLinks = array_merge($aMenuLinks, $aMenuLinksExt); ?>

      Организация показа меню

      Показ меню на страницах сайта выполняется с помощью компонента Меню (bitrix:menu) . Например, вызов верхнего меню на демо-сайте имеет следующий вид.

      Апр 23 2017

      В предыдущих уроках мы разобрали на примерах, что такое массивы. В этом уроке мы используем массивы на практике для создания меню на сайте.

      Чем они удобнее обычных HTML-тегов?

      Ну, допустим, наш сайт имеет 100 страниц, на каждой из которых имеется одно и то же меню. И вдруг нам понадобилось изменить пункты меню. Используя только HTML, нам придётся делать правки на 100 страницах сайта, это очень много. Так вот на помощь в таких ситуациях к нам приходит PHP. Достаточно будет поменять пункты меню всего лишь один раз в одном файле.

      А теперь поехали.

      На локальном хостинге в папке “domains создаём папку под названием “array - menu . local ”.

      В этой папке создаём четыре файла: index . php , about . php , contact . php и menu . php .

      !!! Синтаксис файлов должен быть PHP .

      В файле index.php пишем простой HTML каркас.




      charset ="utf-8" >



      Главная


      include ("menu.php" );
      ?>

      Копируем этот код в файлы about.php и contact.php. Меняем только названия страниц в теге

      .

      Пишем код для меню.

      В файле menu.php пишем ассоциативный массив.

      $menu = array (
      "index"=> "index.php",
      "about"=> "about.php",
      "contacts"=> "contact.php"
      );
      ?>

      Ниже с помощью тегов HTML пишем меню.

      В браузере мы увидим обычное меню в виде списка.

      Кликая на любом пункте меню мы перейдём на соответствующую страницу, меню при этом будет на всех страницах.

      Теперь усложним задачу. Всё удаляем из файла menu.php и...

      Пишем многомерный массив.




      charset ="utf-8" >
      <span>Использование массива для вывода меню на сайте. </span>


      $menu = array (
      array ("link"=> "Главная", "href"=> "index.php" ),
      array ("link"=> "О нас", "href"=> "about.php" ),
      array ("link"=> "Контакты", "href"=> "contact.php" )
      );
      ?>



      И на последнем этапе...

      Отрисовываем меню с помощью цикла foreach .

      Удаляем из файла menu.php список

        и вместо него пишем следующий код.

        echo "

          " ;
          foreach ($menu as $item ){
          echo "
        • {$item }
        • " ;
          }

          В браузере увидим тот же результат.

          Чтобы изменить пункты меню, достаточно изменить их в файле menu.php всего один раз.