За последние 24 часа нас посетили 18669 программистов и 1703 робота. Сейчас ищут 1104 программиста ...

Создание негораниченной вложенности каталога.

Тема в разделе "Прочие вопросы по PHP", создана пользователем Oleg_php, 8 авг 2012.

  1. Oleg_php

    Oleg_php Активный пользователь

    С нами с:
    17 янв 2012
    Сообщения:
    80
    Симпатии:
    0
    Всем привет. Хотел бы узнать, какие методом можено сделать неограниченную систему вложенности каталога с использование таблиц Mysql.

    Пример :
    Код (Text):
    1.  
    2. Каталог -
    3.          | Подкаталог 1 -
    4.                          | Подкаталог 1-1
    5.                          | Подкаталог 1-2
    6.                                          | Подкаталог 1-2-1
    7.                                          | Подкаталог 1-2-2
    8.                                          | Подкаталог 1-2-3
    9.                                          | Подкаталог 1-2-4
    10.                                          | Подкаталог 1-2-5
    11.                          | Подкаталог 1-3
    12.          | Подкаталог 2
    13.          | Подкаталог 3
    и т.п. Как можно реализовать такую систему?
     
  2. Ke1eth

    Ke1eth Активный пользователь

    С нами с:
    16 мар 2012
    Сообщения:
    1.073
    Симпатии:
    11
    Адрес:
    заблудилса
  3. Oleg_php

    Oleg_php Активный пользователь

    С нами с:
    17 янв 2012
    Сообщения:
    80
    Симпатии:
    0
    Спасибо буду изучать. А есть ли ещё какие-нибудь варианты с примерами?

    Добавлено спустя 10 минут 42 секунды:
    Пока решил сделать просто Parent_ID.
     
  4. YSandro

    YSandro Старожил

    С нами с:
    7 апр 2011
    Сообщения:
    2.523
    Симпатии:
    2
    Один из способов вы знаете - это указание id и parent. Ограничений тут нет на количество уровней вложенности. Смотря что вы с этим хотите потом делать.
    Если действительно много уровней, и нужно выводить фрагментами, то Nested sets как раз и есть универсальное и оптимальное решение. Но в будущем возможно появление "тормозов" при добавлении новых элементов в дерево.
    Если же нужно один раз вывести небольшое меню, то достаточно одной рекурсивной функции.
     
  5. Oleg_php

    Oleg_php Активный пользователь

    С нами с:
    17 янв 2012
    Сообщения:
    80
    Симпатии:
    0
    У кого-нибудь есть готовый, рабочий пример?

    Добавлено спустя 5 минут 5 секунд:
    Если таким примером разбить, нормальный вариант?

    Код (Text):
    1.  
    2. $Result = array(
    3.  array('id' => 1, 'parent_id' => 11, 'page' => 'News_1.1'),
    4.  array('id' => 2, 'parent_id' => 0, 'page' => 'Index'),
    5.  array('id' => 3, 'parent_id' => 17, 'page' => 'News_1.2.1'),
    6.  array('id' => 5, 'parent_id' => 0, 'page' => 'News'),
    7.  array('id' => 7, 'parent_id' => 17, 'page' => 'News_1.2.3'),
    8.  array('id' => 8, 'parent_id' => 17, 'page' => 'News_1.2.2'),
    9.  array('id' => 9, 'parent_id' => 0, 'page' => 'About'),
    10.  array('id' => 11, 'parent_id' => 5, 'page' => 'News_1'),
    11.  array('id' => 17, 'parent_id' => 11, 'page' => 'News_1.2'),
    12.  );
    13.  
    14.  function Tree($treeArray, $pid = 0) {
    15.      if (! $treeArray)
    16.      {
    17.      return false;
    18.      }
    19.  
    20.      foreach($treeArray as $item)
    21.      {
    22.         if ($item['parent_id'] == (int) $pid)
    23.         {
    24.         echo($item['page'] . '') ;
    25.         tree($treeArray, $item['id']);
    26.         }
    27.      }
    28.  }
    29.  
    30.  Tree($Result);
    Добавлено спустя 34 секунды:
    Пример с одного сайта.
     
  6. YSandro

    YSandro Старожил

    С нами с:
    7 апр 2011
    Сообщения:
    2.523
    Симпатии:
    2
    Пример чего? Что требуется?
     
  7. Oleg_php

    Oleg_php Активный пользователь

    С нами с:
    17 янв 2012
    Сообщения:
    80
    Симпатии:
    0
    Метод для вывода древовидного каталога. Хотелось бы просто запихнуть его в базовый класс и спользовать для каждого модуля.
     
  8. YSandro

    YSandro Старожил

    С нами с:
    7 апр 2011
    Сообщения:
    2.523
    Симпатии:
    2
    Ну так можно по-разному выводить. Можно вложенными списками ul, li, можно отступами внутри pre, можно div тегами с отступами. Из этого 'page' => 'News_1.1' что должно выйти, ссылка, просто текст? От требуемого представления будет зависеть и реализация. Универсальную функцию не сделать.
     
  9. Oleg_php

    Oleg_php Активный пользователь

    С нами с:
    17 янв 2012
    Сообщения:
    80
    Симпатии:
    0
    Списком Ul li и ссылками.
     
  10. YSandro

    YSandro Старожил

    С нами с:
    7 апр 2011
    Сообщения:
    2.523
    Симпатии:
    2
    Для вывода меню делал пример viewtopic.php?f=13&t=40008&p=324728#p323894
    В базе берутся поля id,parent,title_menu, которые можно поменять под свой случай.
     
  11. Oleg_php

    Oleg_php Активный пользователь

    С нами с:
    17 янв 2012
    Сообщения:
    80
    Симпатии:
    0
    В итоге out можно сделать reutrn'ом. Отлично, большое спасибо. Буду сейчас разбирать.

    Добавлено спустя 44 секунды:
    мы передаём весь массив с базы данных ведь?
     
  12. YSandro

    YSandro Старожил

    С нами с:
    7 апр 2011
    Сообщения:
    2.523
    Симпатии:
    2
    В данном случае да, что совсем не хорошо. Для небольшого количества записей пойдет (думаю, около 5000). Если нужно больше, то как раз лучше Nested sets, т.к. скорость работы мало зависит от количества и вложенности.
     
  13. Oleg_php

    Oleg_php Активный пользователь

    С нами с:
    17 янв 2012
    Сообщения:
    80
    Симпатии:
    0
    Вроде больше 5000 не будет. Просто пока Nested sets схему ещё не до конца понел.

    Добавлено спустя 43 минуты 24 секунды:
    а никакого jquery скрипта случайно в запасе нет, чтобы при наджатии открывались подкатегории?
     
  14. YSandro

    YSandro Старожил

    С нами с:
    7 апр 2011
    Сообщения:
    2.523
    Симпатии:
    2
    Кучу всего писал, трудней искать теперь подходящее, чем написать с нуля. Нажатии чего именно? Тут тоже варианты есть. Если хочется картинку с крестиками поставить, то это будет клик по картинке, на которой нужно поставить обработчик клика, например
    Код (Text):
    1. <li><img src="img/m.gif" id="im%d" onclick="vizibility(%d)" alt=""/><a href=...><ul id="ul%d">...
    вместо %d поставить id элемента. Если же по самой ссылке, то либо ссылка станет нерабочей, либо смысла писать js-скрипт нет, т.к. после клика будет перезагрузка страницы.
     
  15. artem-Kuzmin

    artem-Kuzmin Активный пользователь

    С нами с:
    16 фев 2012
    Сообщения:
    809
    Симпатии:
    0
    Шикарно)) не использовал
     
  16. Oleg_php

    Oleg_php Активный пользователь

    С нами с:
    17 янв 2012
    Сообщения:
    80
    Симпатии:
    0
    А если из нескольких таблиц нужно вывести структуру. Например есть таблица Портфолио, Услуги.
    Как лучше запрос написать для такого варианта :
    Код (Text):
    1. //
    2.     // Генерируем структурное меню
    3.     public function GenerateMenu(&$arr,&$out,$parent=0,&$level=0)
    4.     {  
    5.         // $arr - массив меню.
    6.         // $out - сгенерируемое меню
    7.         // $parent - начальный уровень иерархии меню
    8.         // Уровень
    9.        
    10.         foreach($arr as $row)
    11.         {
    12.         if($row['s_parent']==$parent)
    13.         {
    14.           $sel=($row['s_id']==$id)?' class="sel"':'';
    15.           $level++;          
    16.          
    17.           $out.= str_repeat("\t",$level).'<li '.$sel.'><a href="" '.$sel.'>'.$row['s_title'].'</a>';
    18.          
    19.           $inner='';
    20.           $level++;
    21.           $this->GenerateMenu($arr,$inner,$row['s_id'],$level);
    22.           $level--;
    23.           if(strlen($inner)>0){
    24.             $out.= ''.str_repeat("\t",$level+1).'<ul>'.$inner.''.str_repeat("\t",$level+1).'</ul>'.str_repeat("\t",$level).'';
    25.           }
    26.           $out.="</li>\n";
    27.           $level--;
    28.         }
    29.         }
    30.       return $out;
    31.     }