Помощник
|
Создание древовидного меню, как лучше сделать? |
RussiaStudent
|
Сообщение
#1
|
||
|
|
||
|
|||
НЕПЛОХОЙ |
21.8.2009, 7:35;
Ответить: НЕПЛОХОЙ
Сообщение
#2
|
|
RussiaStudent, http://www.getinfo.ru/article610.html посмотрите вот эту статью, я сам ее не читал еще, но кажется то что надо
Поблагодарили: (0) |
|
|
ZiTosS |
21.8.2009, 10:51;
Ответить: ZiTosS
Сообщение
#3
|
|
Евгений, Читая подобное, думаешь "да разве подобное усложнение нужно в связках древовидного меню". Правые и левые ключи за которыми нужно следить + очень много воздействий на базу данных, так что просто можно её повесить. Так же не очень удобная выборка по ключу, делать ограничения.
Я тут на досуге подумал, всех лучше для создания древовидного меню подойдет одна таблица с примерным содержанием полей id INT(11) auto_increment - идентификатор узла id_parent INT(11) - родительский узел title VARCHAR(255) - заголовок узла ................. Вот что из себя представляют данные 1 | 0 | узел 1 2 | 0 | узел 2 3 | 0 | узел 3 4 | 0 | узел 4 5 | 1 | узел 1_1 6 | 1 | узел 1_2 7 | 2 | узел 2_1 8 | 2 | узел 2_2 9 | 4 | узел 4_1 10 | 4 | узел 4_2 11 | 4 | узел 4_3 12 | 4 | узел 4_4 13 | 10 | узел 4_2_1 14 | 10 | узел 4_2_2 15 | 11 | узел 4_3_1 16 | 11 | узел 4_3_2 Причем порядок следования узлов не важен, так как мы будем спускаться от 0 узла к максимальному. Все записи по уровням будут обработаны в последовательности. Родительский узел 0 означает, что выбранный узел не имеет родителей. Осталось написать функцию с помощью которой можно было бы осуществить постройку дерева и последующую обработку. Я думаю лучше всего бы было хранить связи в многомерном массиве на примере такого array
( [id] => array ( [id] => id [id_parent] => id_parent [title] => title [child] => array ( [id] => array ( [id] => id [id_parent] => id_parent [title] => title [child] => array ( ... ) ), [id] => array ( [id] => id [id_parent] => id_parent [title] => title [child] => array ( ... ) ) ) ), ....................... ) Поблагодарили: (0) |
|
|
yury_mw |
21.8.2009, 10:58;
Ответить: yury_mw
Сообщение
#4
|
|
RussiaStudent,
я не большой спец по базам данных, но мне кажется, что наиболее простой и, соответственно, правильный ;) алгоритм, примерно, такой: * делаем одну табличку с 2мя полями: [id узла] - [id родителя] * если в id родителя - 0, то это корень дерева * для построения потомков конкретного узла делаем выборку по заданному id родителя * для построения всего дерева делаем цикл по всем id узлов ну вот, пока писал, ZiTosS уже что-то похожее закодил ;) Поблагодарили: (0) |
|
|
RussiaStudent
|
Сообщение
#5
|
|
Спасибо всем за ответы. Структура понятна, красиво расписано.
Вообщем-то я тоже подумывал над одной таблице, так как для создания отдельных таблиц под каждую вложенность потребовало бы не малых затрат да и таблиц бы стало слишком много. Постараюсь сегодня написать функцию обхода древовидного меню приведенного выше. Спасибо за наводку, действительно не так всё и сложно. Интересует ещё всё же как легче написать обход дерева? Тут же нужен спуск по древу в каждой ветке. Читал когда-то про рекурсию - вызов самого себя. Может попробовать с помощью неё спуститься по дереву, как кто щитает правильный ли это подход. Или лучше написать обход с помощью while циклов? |
|
|
ZiTosS |
21.8.2009, 23:56;
Ответить: ZiTosS
Сообщение
#6
|
|
RussiaStudent, рекурсия будет самое то. Только не забываем что рекурсивная функция либо должна возвращать массив детей, либо как-то его заносить во внутрь основного массива(тут можно массив по ссылке передавать)
С помощью while возможно не получится. Хотя можно, если составить сначала древо родителей, а потом его обходить и заносить. Но это сколько же лишнего кода. А вот в отношении рекрсии не так всё сложно. Она сама обойдет всё дерево, стоит только правильно функцию сформировать. |
|
|
RussiaStudent
|
Сообщение
#7
|
|
ZiTosS, вот я думаю как же всё таки написать эту функцию рекурсии, воот что-то подумал и написал такое:
[php]function getChildMenu($massiv, $id_parent) { $resource=mysql_query("SELECT * FROM category WHERE id_parent={$id_parent}"); if(mysql_num_rows($resource)){ while($array=mysql_fetch_assoc($resource)){ $massiv[$array['id']]=$array; // здесь вызов рекурсии, но как его организовать } } }[/php] Я тут подумал, как же заносить данные в массив, если в функции мы работаем с копией, и меняя её мы не меняем оригинал, на выходе мы опять же получем пустоту. И как же мне вызвать рекурсию? |
|
|
ZiTosS |
22.8.2009, 12:55;
Ответить: ZiTosS
Сообщение
#8
|
|
RussiaStudent,
как же заносить данные в массив, если в функции мы работаем с копией, и меняя её мы не меняем оригинал, на выходе мы опять же получаем пустоту В языках программирование есть такое понятие, "Передача по ссылке" - что означает передача оригинала для работы с ним. Чтобы организовать в PHP передачу по ссылке достаточно перед переменной куда хотим передать ссылку поставить амперсанд ( & ): [php]function nameFunction(&$ref, $copy) { // $ref - переданное по ссылке ( изменяя в функции, изменим и оригинал ) // $copy - копия ( изменяя в функции, оригинал не изменяется ) $ref = 1; $copy = 1; } $param1 = $param2 = 0; # вызываем функцию. nameFunction($param1, $param2); // Теперь $param1 = 1; $param2 = 0[/php] И как же мне вызвать рекурсию? Сначала тебе нужно создать подмассив детей, ключем к нему будет "child". А затем для него вызвать рекурсию. Типа этого: [php]....................... $massiv[$array['id']]['child'] = array(); // создаём элемент массива для хранения детей getChildMenu($massiv[$array['id']]['child'], $array['id_parent']); // вызываем рекурсию в качестве параметров (элемент(массив) хранения детей, родительский уровень(будем захватывать элементы, принадлежащие родительскому id)) .......................[/php] Поблагодарили: (0) |
|
|
RussiaStudent
|
Сообщение
#9
|
|
|
ZiTosS, спасибо всё получилось. Вот написал де функции рекурсивных, одна собирает массив, а другая обрабатывает его и создаёт HTML-меню.
Функция создания древовидного массива: [php]// Параметры: наш формирующийся массив $menu_child (по ссылке), наш текущий родительский уровень $id_parent (по умолчанию 0) function getChildMenu(&$menu_child, $id_parent = 0) { $resource=mysql_query("SELECT * FROM category WHERE id_parent={$id_parent}"); // вытаскиваем все меню(категории), которые соответствуют родительскому ID // если записей не нуль if(mysql_num_rows($resource) > 0) { // обрабатываем в цикле все записи while($array=mysql_fetch_array($resource)) { $menu_child[$array['id']]=$array; // заносим в массив данные элемента(id, id_parent, title) $menu_child[$array['id']]['child']=array(); // создаём раздел, куда будем детей добавлять getChildMenu($con, $menu_child[$array['id']]['child'], $array['id']); // (рекурсивный вызов) в качестве параметров массив с ключем 'child' и текущий ID } } }[/php] Функция создания HTML (ul/li) меню: [php]// Параметры: переменная, куда будем формировать контент $content (по ссылке), массив из которого формируем (должен быть в специально форме) function printChildMenu(&$content, $menu) { // начинаем обход массива $menu в цикле по записям foreach($menu as $value) { // если у текущего элемента нет детей if(count($value['child'])==0) $content.="<li><a href='./products_{$value['id']}.html'>{$value['title']}</a></li>"; // заносим элемент списка li // если у текущего элемента есть дети else { $content.="<li><a href='./products_{$value['id']}.html'>{$value['title']}</a><ul>"; // заносим элемент списка li и открываем список детей printChildMenu($content, $value['child']); // (рекурсивный вызов) обходим детей элемента для формирования списка $content.="</ul></li>"; // заносим конец списка детей. } } }[/php]
|
|
|
||
|
Похожие темы
Тема | Ответов | Автор | Просмотров | Последний ответ | |
---|---|---|---|---|---|
как заслужить право на создание новой темы? | 7 | writer80 | 2089 | 12.3.2024, 22:54 автор: Lumex |
|
<Braga/> Создание Telegram-ботов, web-приложений, крипто-бирж, сайтов. | 2 | newbraga | 1614 | 10.3.2024, 22:04 автор: newbraga |
|
СОЗДАНИЕ : / САЙтЫ / ЛЕНДЫ / БОТЫ ТГ / ВАЙТЫ / КРЕО / СОФТЫ / ДИЗАЙН [PHP, JS, HTML/CSS] и другое | 5 | CULA | 3244 | 19.12.2023, 18:55 автор: CULA |
|
Создание и ведение аккаунтов в соцсетях ("В контакте"/Telegram) Услуги от профессионального журналиста и SMM-менеджера |
2 | AvtorXXX | 1636 | 13.11.2023, 23:47 автор: AvtorXXX |
|
Создание информационной площадки с доской объявлений | 1 | xweb | 2030 | 16.1.2023, 16:25 автор: xweb |
Текстовая версия | Сейчас: 19.3.2024, 18:01 |