Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Многоуровневое меню. Алгоритм.
 
 автор: boom.olezka   (19.09.2007 в 12:59)   письмо автору
 
 

Нашёл кучу тем, по этой теме :) Но мне всё равно мало, или некоторые моменты мне не понятны...

Есть табличка, как всегда

id | pid
1 | 0
2 | 1
3 | 1
4 | 2
5 | 0
6 | 4
7 | 2

При клике на определёный пункт меню раскрывается :) Глубина не ограничена! Нажал на id=1 раскрылись и увидел id=2, id=3, дальше нажал на id=2 раскрылись и увидел id=7. Стандарное много уровневое меню...

В одном из топиков, был такой же вопрс... Там посоветовали:


создаете в базе (или в файле) следующую структуру:
id (идентификатор пункта меню), parent_id (идентификатор родительского пункта меню), наименование, ссылка и пр.

строим дерево:
в корневой группе пункты имеющие parent_id=NULL
если id данного пунктасовпадает с выбранным - разворачиваем его: выводим все пункты где parent_id=id_текущего_пункта.
и так далее до конца дерева.
Если вложенность неограниченная, желательно использовать рекурсивную функцию.


я конечно могу ошибаться, но это не совсем то что мне надо :) А если активный раздел находится на 3 уровне, то как тогда его id (выбранный) совпадёт с id (корневой) у которого parent_id=NULL.

Я прошу на словах разъяснить мне теориую... Как писать рекурсивные функции я знаю, так что смело объясняйте :)

   
 
 автор: RV   (19.09.2007 в 13:55)   письмо автору
 
   для: boom.olezka   (19.09.2007 в 12:59)
 

shop-script.ru
там есть бесплатный интернет магазин.
и в нем организованно вложенное меню с бесконечными вложениями

   
 
 автор: Loki   (19.09.2007 в 14:02)   письмо автору
 
   для: boom.olezka   (19.09.2007 в 12:59)
 

>я конечно могу ошибаться, но это не совсем то что мне надо :) А если активный раздел находится на 3 уровне, то как тогда его id (выбранный) совпадёт с id (корневой) у которого parent_id=NULL.

А он и не совпадает - его находят.
вот ваше собственное дерево:

1
-2
--4
---6
--7
-3
5

Что с чем должно совпадать?

   
 
 автор: boom.olezka   (19.09.2007 в 14:12)   письмо автору
 
   для: Loki   (19.09.2007 в 14:02)
 

Как я понимаю ваш алгоритм выводит всё дерево, а мне не надо выводить всё дерево.
Пример 1: Я выбрал id=1 вижу
1
-2
5

Пример 2: из премера 1я выбрал id=2 вижу
1
-2
--4
--7
5

   
 
 автор: Гена V   (19.09.2007 в 15:18)   письмо автору
 
   для: boom.olezka   (19.09.2007 в 14:12)
 

Напиши функцию.......которая выбирает по паренту........смотри.....передается ай ди категории.......это парент для подкатегорий.........т.е. не всю выборку делай.......а по ай ди............

   
 
 автор: Gust   (19.09.2007 в 15:35)   письмо автору
 
   для: boom.olezka   (19.09.2007 в 14:12)
 

а 3 когда появится?

Решение, наверно, будет сводится к следующему:
1. Рекурсией идешь от выбранного ID до корневого родителя, находя его ID и собирая открытую ветку;
2. Запрашиваешь корневые записи без найденого ID родителя ветки для основного меню
3. Запрашиваешь всех прямых потомков выбранного ID для формирования ветки вложения.
4. Все это сшиваешь в дерево.

   
 
 автор: Loki   (19.09.2007 в 16:35)   письмо автору
 
   для: Gust   (19.09.2007 в 15:35)
 

1. не нужна тут рекурсия - больше одного родителя ни у кого нет, а потомков запрашиваем всего на один уровень вглубь.

   
 
 автор: Gust   (20.09.2007 в 07:15)   письмо автору
 
   для: Loki   (19.09.2007 в 16:35)
 

>1. не нужна тут рекурсия - больше одного родителя ни у кого нет, ...
как уточнил автор
>... Глубина не ограничена! ...
не значит ли это что у родителя тоже может быть родитель?

>...а потомков запрашиваем всего на один уровень вглубь.
под прямыми потомками я именно это и имел

   
 
 автор: Loki   (20.09.2007 в 09:39)   письмо автору
 
   для: Gust   (20.09.2007 в 07:15)
 

>не значит ли это что у родителя тоже может быть родитель?
это значит что при такой структуре у любого элемента всего один родитель. Рекурсия используется в том случае, когда количество связанных элементов неизвестно.

   
 
 автор: Gust   (20.09.2007 в 11:02)   письмо автору
 
   для: Loki   (20.09.2007 в 09:39)
 

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

Что 1 родитель это понятно, а как вы предлагаете найти нулевого родителя у выбранного ID (скажем в 5 вложении), чтобы знать какой пункт основного меню нужно раскрыть, а какие оставить свернутыми?

   
 
 автор: Loki   (20.09.2007 в 11:58)   письмо автору
 
   для: Gust   (20.09.2007 в 11:02)
 

обычным циклом. или вам еще код написать?

   
 
 автор: Gust   (20.09.2007 в 12:48)   письмо автору
 
   для: Loki   (20.09.2007 в 11:58)
 

>обычным циклом. ...
да, пожалуй, предполагаю логика была бы запросить все записи с обратной сортировкой по родителю и перебрать их в цикле до 0-родителя.
>...или вам еще код написать?
только если я не правильно предположил (можно только логику)

   
 
 автор: Loki   (20.09.2007 в 13:36)   письмо автору
 
   для: Gust   (20.09.2007 в 12:48)
 

Вариант первый.
Для случая, когда вложенность большая, но конечная

SELECT t1.id, t2.id, t3.id, t4.id ...
FROM table t1 
LEFT JOIN table t2 ON t1.parent_id=t2.id
LEFT JOIN table t3 ON t2.parent_id=t3.id
LEFT JOIN table t4 ON t3.parent_id=t4.id
...
WHERE t1.id=искомый id

Для реальных задач уровня вложенности 10 хватает за глаза, но для маньяков - mysql поддерживает, если не путаю, до 128 уровня.

Вариант второй.
Если нам нужна реально бесконечная вложенность.

<?

$id
=10//искомый id
$tmp=$id;
$parents=array();
while (
$tmp)
{
    
$parents[]=$tmp;
    
$result=mysql_query("SELECT parent_id FROM table WHERE id=$tmp");
    
$tmp=mysql_result($result0);
}

print_r($parents);


Все. Никакой рекурсии.

   
 
 автор: boom.olezka   (19.09.2007 в 16:02)   письмо автору
 
   для: boom.olezka   (19.09.2007 в 12:59)
 

Всем спасибо, посмотрел скрипты от shop-script то что надо :) Но буду ещё пробывать :)

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования