Сортировка многоуровневого меню на PHP + MySQL

Сортировка многоуровневого меню на PHP + MySQL

Сортировка многоуровневого меню на PHP + MySQL

Если Вы не читали предыдущую часть статьи, то ознакомитесь с ней ( Многоуровневое меню на PHP + MySQL )

После того как вы создали многоуровневое меню, возникает резонный вопрос, как его отсортировать в нужном порядке? Первое что приходит в голову это создать в таблице с меню еще один столбец ( sort ) и в нем указывать номерную сортировку. Но так как у нас вся менюшка хранится в одной таблице и имеет родителей и потомков у которых номера сортировки могут совпадать, то сортировка простыми средствами MySQL становится не возможной. На помощь приходит PHP. Будем использовать функцию сравнения для сортировки массива, перед тем как создать из него дерево зависимостей. Тем самым получим отсортированное меню в том виде которое нам нужно.

Первое что нам нужно – добавить колонку в нашу таблицу с меню для сортировки и выставить нужные значения.

Модернизируем таблицу Categories.

  
    --
    -- Структура таблицы `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,
    `sort` int(11) NOT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=20 ;

    --
    -- Дамп данных таблицы `categories`
    --

    INSERT INTO `categories` (`id`, `title`, `parent`, `sort`) VALUES
    (1, 'Автомобили', 0, 1),
    (2, 'Мотоциклы', 0, 2),
    (3, 'Мазда', 1, 1),
    (4, 'Хонда', 1, 2),
    (5, 'Кавасаки', 2, 2),
    (6, 'Харлей', 2, 1),
    (7, 'Мазда 3', 3, 2),
    (8, 'Мазда 6', 3, 1),
    (9, 'Седан', 7, 2),
    (10, 'Хечбэк', 7, 1),
    (11, 'Лодки', 0, 3),
    (12, 'Лифтбэк', 8, 2),
    (13, 'Кроссовер', 8, 1),
    (14, 'Белый', 13, 1),
    (15, 'Красный', 13, 2),
    (16, 'Черный', 13, 3),
    (17, 'Зеленый', 13, 4),
    (18, 'Мазда CX', 3, 3),
    (19, 'Мазда MX', 3, 4);
  

Далее пишем функцию сравнения для сортировки массива.

  
    //Функция сравнения для сортировки
    function sortCat($a, $b){
      if ($a['sort'] == $b['sort']) {
        return 0;
      }
      return ($a['sort'] < $b['sort']) ? -1 : 1;
    }
  

Вызываем функцию uasort вместе с нашей функцией сравнения передав в виде аргумента массив с меню.

  
    //Функция построения дерева из массива от Tommy Lacroix
    function getTree($dataset) {
      $tree = array();
      //Сортируем массив перед созданием из него дерева
      uasort($dataset, 'sortCat');

      foreach ($dataset as $id => &$node) {
        //Если нет вложений
        if (!$node['parent']){
          $tree[$id] = &$node;
        }else{
          //Если есть потомки то перебераем массив
          $dataset[$node['parent']]['childs'][$id] = &$node;
        }
      }
      return $tree;
    }
  

Теперь у нас полноценное отсортированное в нужном порядке многоуровневое меню для сайта.

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

  
<?php

//Устанавливаем кодировку и вывод всех ошибок
header('Content-Type: text/html; charset=UTF-8');
error_reporting(E_ALL);

//Объектно-ориентированный стиль
$mysqli = new mysqli('localhost', 'user', 'password', 'database');

//Устанавливаем кодировку utf8
$mysqli->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();
    uasort($dataset, 'sortCat');

    foreach ($dataset as $id => &$node) {    
        //Если нет вложений
        if (!$node['parent']){
            $tree[$id] = &$node;
        }else{ 
            //Если есть потомки то перебераем массив
            $dataset[$node['parent']]['childs'][$id] = &$node;
        }
    }
    return $tree;
}

//Функция сравнения для сортировки
function sortCat($a, $b){
    if ($a['sort'] == $b['sort']) {
        return 0;
    }
    return ($a['sort'] < $b['sort']) ? -1 : 1;
}

//Получаем подготовленный массив с данными
$cat  = getCat($mysqli); 

//Создаем древовидное меню
$tree = getTree($cat);

//Шаблон для вывода меню в виде дерева
function tplMenu($category){
    $menu = '<li>
        <a href="#" title="'. $category['title'] .'">'. 
        $category['title'].'</a>';
        
        if(isset($category['childs'])){
            $menu .= '<ul>'. showCat($category['childs']) .'</ul>';
        }
    $menu .= '</li>';
    
    return $menu;
}


/**
* Рекурсивно считываем наш шаблон
**/
function showCat($data){
    $string = '';
    foreach($data as $item){
        $string .= tplMenu($item);
    }
    return $string;
}

//Получаем HTML разметку
$cat_menu = showCat($tree);

//Выводим на экран
echo '<ul>'. $cat_menu .'</ul>';

?>
  

Скачать: Сортировка многоуровневого меню на PHP + MySQL


Поддержи проект:

No-name
Дмитрий
Спасибо!

01/10/2021 00:37:12

Админ
Админ

Пользуйтесь! )

01/10/2021 10:52:32

No-name
Иван
Здравствуйте. Спасибо за ваш сайт, очень понравился!  Скажите как можно сделать, что бы при клике на родительскую категорию открывался шаблон с категориями

27/03/2017 21:41:29

Администрация
Администрация

Иван используйте http://getbootstrap.com/components/#nav-dropdowns или http://mm.onokumus.com/mm-vertical.html

28/03/2017 14:09:04

No-name
Alexey
У меня есть вот такая структура (категории и подкатегории): 1  1.1.     1.1.1      1.1.2  1.2.    1.2.1     1.2.2 Необходимо отсортировать дочерние элементы и задать требуемый уровень вложенности для отображения на странице. Например при уровне вложенности 1 получится такой вывод : 1 1.1 1.2 И так далее Если задать уровень вложенности 2, то соответственно должны отображаться элементы 2 уровня вложенности

19/12/2016 09:11:27

Администрация
Администрация

Алексей в принципе меню так и построено, вам нужно нужно выставить родителей в поле parent и указать сортировку данного меню. Как привязвать категории к подкатегориям смотрите в табличке http://bezramok-tlt.ru/?mode=2&post=21

02/02/2017 13:37:55

No-name
alexey
Здравствуйте. Подскажите пожалуйста , какие изменения нужно внести в код, чтобы меню отображалось  с заданным уровнем вложенности  ? Например необходимо вывести только дочерние элементы первого уровня.

18/12/2016 22:50:21

Администрация
Администрация

Вы имеете ввиду вывод конкретной категории, ее подкатегорий как для интернет магазина? Киньте ссылку на пример того что Вы хотите.

 

19/12/2016 08:34:22

No-name
Alexey
Здравствуйте. Очень полезная статья. Подскажите пожалуйста можно ли сделать из этого списка раскрывающийся  с добавлением  в вывод каких либо полей из базы?   Например так : Лодк и ссылка на описание Автомобили ссылка на описание При открытии дочерних элементов соответственно будут отображаться ссылки на описание дочерних элементов Есть ли пример кода ? Очень нужно. 

12/11/2016 09:14:25

Администрация
Администрация

Создайте еще одну таблицу и записывайте в нее описание, таблицы свяжите по ID с меню. При клике по ссылке запросом достаете нужный контент из таблицы с описанием.

13/11/2016 09:50:39

No-name
Андрій
Дуже дякую, Ви мені допомогли!! Довго ламав голову як це зробити!!! Ви геній!

26/06/2016 11:22:50

Администрация
Администрация

Не за что. Сам долго голову ломал как это сделать, в итоге родилось решение этого вопроса.

26/06/2016 14:16:36


Copyright © 2014 - 2024 All rights reserved.