Всем привет. Хотел бы узнать, какие методом можено сделать неограниченную систему вложенности каталога с использование таблиц Mysql. Пример : Код (Text): Каталог - | Подкаталог 1 - | Подкаталог 1-1 | Подкаталог 1-2 | Подкаталог 1-2-1 | Подкаталог 1-2-2 | Подкаталог 1-2-3 | Подкаталог 1-2-4 | Подкаталог 1-2-5 | Подкаталог 1-3 | Подкаталог 2 | Подкаталог 3 и т.п. Как можно реализовать такую систему?
Спасибо буду изучать. А есть ли ещё какие-нибудь варианты с примерами? Добавлено спустя 10 минут 42 секунды: Пока решил сделать просто Parent_ID.
Один из способов вы знаете - это указание id и parent. Ограничений тут нет на количество уровней вложенности. Смотря что вы с этим хотите потом делать. Если действительно много уровней, и нужно выводить фрагментами, то Nested sets как раз и есть универсальное и оптимальное решение. Но в будущем возможно появление "тормозов" при добавлении новых элементов в дерево. Если же нужно один раз вывести небольшое меню, то достаточно одной рекурсивной функции.
У кого-нибудь есть готовый, рабочий пример? Добавлено спустя 5 минут 5 секунд: Если таким примером разбить, нормальный вариант? Код (Text): $Result = 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 false; } foreach($treeArray as $item) { if ($item['parent_id'] == (int) $pid) { echo($item['page'] . '') ; tree($treeArray, $item['id']); } } } Tree($Result); Добавлено спустя 34 секунды: Пример с одного сайта.
Метод для вывода древовидного каталога. Хотелось бы просто запихнуть его в базовый класс и спользовать для каждого модуля.
Ну так можно по-разному выводить. Можно вложенными списками ul, li, можно отступами внутри pre, можно div тегами с отступами. Из этого 'page' => 'News_1.1' что должно выйти, ссылка, просто текст? От требуемого представления будет зависеть и реализация. Универсальную функцию не сделать.
Для вывода меню делал пример viewtopic.php?f=13&t=40008&p=324728#p323894 В базе берутся поля id,parent,title_menu, которые можно поменять под свой случай.
В итоге out можно сделать reutrn'ом. Отлично, большое спасибо. Буду сейчас разбирать. Добавлено спустя 44 секунды: мы передаём весь массив с базы данных ведь?
В данном случае да, что совсем не хорошо. Для небольшого количества записей пойдет (думаю, около 5000). Если нужно больше, то как раз лучше Nested sets, т.к. скорость работы мало зависит от количества и вложенности.
Вроде больше 5000 не будет. Просто пока Nested sets схему ещё не до конца понел. Добавлено спустя 43 минуты 24 секунды: а никакого jquery скрипта случайно в запасе нет, чтобы при наджатии открывались подкатегории?
Кучу всего писал, трудней искать теперь подходящее, чем написать с нуля. Нажатии чего именно? Тут тоже варианты есть. Если хочется картинку с крестиками поставить, то это будет клик по картинке, на которой нужно поставить обработчик клика, например Код (Text): <li><img src="img/m.gif" id="im%d" onclick="vizibility(%d)" alt=""/><a href=...><ul id="ul%d">... вместо %d поставить id элемента. Если же по самой ссылке, то либо ссылка станет нерабочей, либо смысла писать js-скрипт нет, т.к. после клика будет перезагрузка страницы.
А если из нескольких таблиц нужно вывести структуру. Например есть таблица Портфолио, Услуги. Как лучше запрос написать для такого варианта : Код (Text): // // Генерируем структурное меню public function GenerateMenu(&$arr,&$out,$parent=0,&$level=0) { // $arr - массив меню. // $out - сгенерируемое меню // $parent - начальный уровень иерархии меню // Уровень foreach($arr as $row) { if($row['s_parent']==$parent) { $sel=($row['s_id']==$id)?' class="sel"':''; $level++; $out.= str_repeat("\t",$level).'<li '.$sel.'><a href="" '.$sel.'>'.$row['s_title'].'</a>'; $inner=''; $level++; $this->GenerateMenu($arr,$inner,$row['s_id'],$level); $level--; if(strlen($inner)>0){ $out.= ''.str_repeat("\t",$level+1).'<ul>'.$inner.''.str_repeat("\t",$level+1).'</ul>'.str_repeat("\t",$level).''; } $out.="</li>\n"; $level--; } } return $out; }