- Алгоритм построения древа каталога
- 2 ответа 2
- Как работает алгоритм
- Многоуровневое меню на PHP + MySQL
- Далее переходим от слов к практике. Создадим таблицу Categories.
- Алгоритм работы состоит из следующего:
- Создаем соединение с базой данных
- Пишем функцию получения данных из таблицы Categories
- Получаем массив вот такого вида, где ключ массива это ID категории.
- Функция построения дерева из массива от Tommy Lacroix
- Получаем массив в виде дерева
- Скрипт целиком
- Результат работы
- Многоуровневое меню на PHP + MySQL для админки
- Построение дерева иерархии с помощью PHP и MySQL
Алгоритм построения древа каталога
вам нужна функция, которая будет проходить по массиву и находить для каждого элемента родителя (если parentID != 0) и записывать этот элемент в дети родителя (по ссылке), после чего будет удалять все элементы массива, у которых parentID != 0. В результате у вас останутся только те деревья, чьи корни действительно являются корневыми элементами искомого дерева. Если будет время, позже напишу пример.
основную суть алгоритма я представляю так: берем строку если родитель == 0 $array[id]=$name; иначе $array[parentID][]=$name; берем следующую строку и все заново. Логично?
2 ответа 2
Таблица в базе данных:
+--+-------------+--------+ |id|name |parentid| +--+-------------+--------+ |1 |Имя раздела 1|0 | |2 |Имя раздела 2|0 | |3 |Имя раздела 3|1 | |4 |Имя раздела 4|2 | |5 |Имя раздела 5|4 | |6 |Имя раздела 6|2 | +--+-------------+--------+
Массив, полученный после выборки из базы данных:
$arr = array( array( 'id' => '1', 'name' => 'Имя раздела 1', 'parentid' => '0' ), array( 'id' => '2', 'name' => 'Имя раздела 2', 'parentid' => '0' ), array( 'id' => '3', 'name' => 'Имя раздела 3', 'parentid' => '1' ), array( 'id' => '4', 'name' => 'Имя раздела 4', 'parentid' => '2' ), array( 'id' => '5', 'name' => 'Имя раздела 5', 'parentid' => '4' ), array( 'id' => '6', 'name' => 'Имя раздела 6', 'parentid' => '2' ), );
Функции, для рекурсивного построения дерева:
Примеры использования
Вариант А:
$tree = form_tree($arr); echo build_tree($tree, 0);
$tree = form_tree($arr); echo build_tree($tree, 2);
Как работает алгоритм
Исходный массив обрабатывается функцией form_tree(); . Она формирует массив следующего вида:
$arr = array( 0 => array( array( 'id' => '1', 'name' => 'Имя раздела 1', 'parentid' => '0' ), array( 'id' => '2', 'name' => 'Имя раздела 2', 'parentid' => '0' ), ), 1 => array( array( 'id' => '3', 'name' => 'Имя раздела 3', 'parentid' => '1' ), ), 2 => array( array( 'id' => '4', 'name' => 'Имя раздела 4', 'parentid' => '2' ), array( 'id' => '6', 'name' => 'Имя раздела 6', 'parentid' => '2' ), ), 4 => array( array( 'id' => '5', 'name' => 'Имя раздела 5', 'parentid' => '4' ), ), );
Как можно видеть, элементы исходного массива были разбиты на группы, согласно их родителю. В итоге получилась схема вида: родитель => массив потомков .
Далее, функция build_tree() рекурсивно обрабатывает этот массив.
Она начинает свою работу с ID раздела, указанного в качестве корневого.
В первую очередь, она стремится перебрать потомков данного раздела. В процессе перебора функция проверяет, а не является ли текущий потомок в свою очередь чьим-то родителем? Для этого функция вызывает саму себя, с указанием в качестве ID корневого раздела ID текущего элемента.
Рассмотрим работу алгоритма на примере «Вариант А»:
- Мы начинаем перебор с ID = 0 , в качестве корневого.
- Первый раздел, который мы встречаем во время перебора, это Имя раздела 1 .
- Выводим этот раздел.
- Начинаем перебор с ID = 1 , в качестве корневого.
- Первый раздел, который мы встречаем во время перебора, это Имя раздела 3 .
- Выводим этот раздел.
- Мы начинаем перебор с ID = 3 , в качестве корневого.
- Подразделов нет, функция завершает свою работу.
- Начинаем перебор с ID = 2 , в качестве корневого.
- Первый раздел, который мы встречаем во время перебора, это Имя раздела 4 .
- Выводим этот раздел.
- Мы начинаем перебор с ID = 4 , в качестве корневого.
- Первый раздел, который мы встречаем во время перебора, это Имя раздела 5 .
- Выводим этот раздел.
• Мы начинаем перебор с ID = 5 , в качестве корневого.
• Подразделов нет, функция завершает свою работу. - Разделов больше нет, функция завершает свою работу.
- Мы начинаем перебор с ID = 6 , в качестве корневого.
- Подразделов нет, функция завершает свою работу.
В примере выше, уровень вложенности соответствует тому, в который раз по счету функция build_tree() вызвала сама себя.
Источник
Многоуровневое меню на PHP + MySQL
Ни один сайт не обходится без навигации или как еще называют «меню сайта». Так вот меню сайта бывает одноуровневым и многоуровневым в виде дерева. Если с одноуровневым меню особых сложностей в плане реализации не возникает, то при создании многоуровневого меню нужно хорошо подумать.
Самое главное в этой задаче это спроектировать базу данных для нашего многоуровневого меню. Создадим таблицу Categories с тремя полями id , title , parent где:
- ID – идентификатор
- Title – Название меню
- Parent – Родитель категории по умолчанию 0
За ветвление меню отвечает поле Parent если Parent = 0 , то эта категория является родительской. Для того чтобы добавить потомков к родительской категории нужно в поле parent указать ID нужного родителя. Например:
Таблицы с категориями
ID TITLE PARENT 1 Автомобили 0 2 Мотоциклы 0 3 Мазда 1 4 Хонда 1 5 Кавасаки 2 6 Харлей 2 7 Лодки 0 Как видно из таблицы, у родительской категории Автомобили есть два потомка – это Мазда и Хонда связанных по полю 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);
Алгоритм работы состоит из следующего:
- Создаем соединение с базой данных
- Получаем все данные из таблицы Categories
- Обрабатываем полученные данные изменив ключ массива на номер ID
- Из обработанного массива строим дерево зависимостей неограниченной вложенности используя метод рекурсии для построения
- Выводим наше многоуровневое меню на экран
Создаем соединение с базой данных
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())
Пишем функцию получения данных из таблицы 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; >
Получаем массив в виде дерева
Скрипт целиком
Результат работы
Многоуровневое меню на 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 ''; ?>
Источник
Построение дерева иерархии с помощью PHP и MySQL
Рассмотрим пример построения дерева иерархии (в развернутом виде) на основе информации из базы данных с помощью PHP и MySQL. Ключ к решению данной задачи — использование рекурсивной функции. Иерархия разделов будет храниться в таблице базы данных MySQL.
Ниже на скриншоте показана данная таблица (catalogue):
id — первичный ключ таблицы
pid — id родительского разделаДалее напишем следующий PHP-скрипт:
1. Файл dbopen.php (открывает соединение с MySQL)
$hostName = "";
$userName = "yura";
$password = "yura";
$databaseName = "tree";
if (!($link=mysql_connect($hostName,$userName,$password)))
printf("Ошибка при соединении с MySQL !\n");
exit();
>
if (!mysql_select_db($databaseName, $link))
printf("Ошибка базы данных !");
exit();
>
?>
2. Файл index.php (основной скрипт)
Всю работу выполняет рекурсивная функция ShowTree() . Ниже на скриншоте показан пример работы index.php :
Пример проекта прилагается: phptree.zip
Автор скрипта: Юрий ХристофоровСодержаниеПроверка индексации страницыДругие инструменты Если нужно быстро проверить индексацию одной страницы, можно воспользоваться оператором
СодержаниеСтатистика использования мобильных устройствИзменение поискового индекса GoogleИндексирование с ориентацией на мобильные устройстваПроверка оптимизации для
В конце марта прошла конференция eTarget.Ecommerce, посвященная продвижению интернет-магазинов. Эксперты рассказали о том, как
Если я правильно понял, то при каждой итерации идет обращение к базе данных. Как по мне, — не очень хорошая практика. Если вложеность дерева большая, то затратно… Как по мне, — лучне за раз выгребать все данные, а потом в пхп строить дерево по полученым данным или хранить деревя в файле. Если например надо построить меню сайта, можно закидывать все в іni or xml or json or yaml файл, а потом просто за раз выгребать и все.
Мне больше нравится способ с конфигурационным файлом.. Я сейчас повсеместно использую Zend Framework. Там есть компонента Zend_Config_Writer . Тоесть когда приходится редактировать конфигурационный файл используем ее. А когда нужно использовать конфигурацию, берем просто Zend_Config, который выгребает готовое дерево с конфиг файла в виде массва.
На сколько я знаю, доступ к файлу ПХП делает скорее чем к базе даных.. Хотя точно не буду утверждать..вот пример обработки результата виборки с базы данных:
$queryResult = array(
array('id' => 1, 'parent_id' => 11, 'page' => 'News_1.1'),
array('id' => 2, 'parent_id' => 0, 'page' => 'Index'),
array('id' => 3, 'parent_id' => 17, 'page' => 'News_1.2.1'),
array('id' => 5, 'parent_id' => 0, 'page' => 'News'),
array('id' => 7, 'parent_id' => 17, 'page' => 'News_1.2.3'),
array('id' => 8, 'parent_id' => 17, 'page' => 'News_1.2.2'),
array('id' => 9, 'parent_id' => 0, 'page' => 'About'),
array('id' => 11, 'parent_id' => 5, 'page' => 'News_1'),
array('id' => 17, 'parent_id' => 11, 'page' => 'News_1.2'),
); function tree($treeArray, $pid = 0) if (! $treeArray) return;
>
foreach($treeArray as $item) if ($item['parent_id'] == (int) $pid) echo($item['page'] . '') ;
tree($treeArray, $item['id']);
>
>
> tree($queryResult);Не гарантирую, что самое оптимальное решение, но все же…
А я использую ajax поэтому у меня дерево не бывает затратным, разве что затраты идут только на прорисовку открытой ветки, которая изначально открывается, чтобы поисковику было понятно, где мы находимся в дереве, остальное грузится через json через ajax. Так что прорисовка дерева на клиенте идет :- ))
а что там показывать… все элементарно просто..
1. Закидываете, напр. в базу запись с полями іd, navigation_title, parent_id.
2. Далее при клике на пункте навигации отправляем аjax запрос, через тот же jquery, и параметром передаем id кликнутого пункта…
3. на сервере вигребаем с базы все пункты меню, где parent_id = нашему id, который мы получили параметром, выгребенные даные отправляем обратно в json формате…
4. На странице с которой был отправлен ajax-запрос получаем ответ, и если мы получили не пустой json-объект, строим DOM-дерево через javascript… p.s. можно вместо базы брать даные из того php-массива, или json файла, можно, если совсем по феншую реализовать систему кеширования.. корочче много чего можно…Источник