За последние 24 часа нас посетили 17482 программиста и 1707 роботов. Сейчас ищут 1804 программиста ...

Доска объявлений

Тема в разделе "PHP для новичков", создана пользователем nAgi, 12 ноя 2008.

  1. nAgi

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

    С нами с:
    12 сен 2007
    Сообщения:
    43
    Симпатии:
    0
    пишу доску объявлений и столкнулся с проблемой создания разделов и категьорий, а именно нужно сделать возможность вложений хотябы до 3 уровней.

    Созадал базу для разделов 1 уровень: id название
    Созадал базу для подраздела 2 уровень: id название idразедла

    сижу вот и думую как можно сделть много уровность, понимаю что нужно хранить массив idразделов но в какой таблице непойму. дайти подсказу или примерчик кода очень нужна ваша помащь :(
     
  2. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
  3. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    nAgi
    В DLE сделано так: каждый раздел имеет уникальный id и поле parent_id - т.е. id родительского раздела. Соответственно, разделы, у которых parent_id=1 - выводятся в разделе с id=1, при этом как видишь сама собой отпадает проблема вложености.
     
  4. nAgi

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

    С нами с:
    12 сен 2007
    Сообщения:
    43
    Симпатии:
    0
    да если два уровня проблемы нет ное сли их 10 и каждые еще 10 может иметь
     
  5. Frozen

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

    С нами с:
    20 окт 2008
    Сообщения:
    540
    Симпатии:
    0
    Адрес:
    Москва
    теж написали:

    так можно до бесконечности, а если хочеш чтоб это еще и быстро работало - опять же http://phpclub.ru/faq/Tree?v=w5u
     
  6. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    забыли сказать что при рекурсивной структуре каталогов не стоит забывать о кешировании
     
  7. xak2(2)

    xak2(2) Активный пользователь

    С нами с:
    5 ноя 2008
    Сообщения:
    35
    Симпатии:
    0
    Адрес:
    Latvia, Riga
    Речь я понимаю идет именно о выводе дерева. Так что парент само собой но вот алгоритм подщета вывода это другое дело. Гдето здесь на форуме уже встречался такой вопрос, написаный помойму мною же ака xak2. Поищи внимательнее там ктото писал красивый алгоритм.
     
  8. Vitas

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

    С нами с:
    7 фев 2006
    Сообщения:
    595
    Симпатии:
    0
    Адрес:
    Новосибирск, Академгородок
    В данной ситуации Nested Sets как раз то, что надо.
     
  9. nAgi

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

    С нами с:
    12 сен 2007
    Сообщения:
    43
    Симпатии:
    0
    ВОТ СОБРАЛ КОНСТРУКТОР ИЗ СКРИПТОВ

    ВОТ СОБРАЛ КОНСТРУКТОР ИЗ СКРИПТОВ КОТРЫЕ НАШЕЛ НА ФОРУМЕ.
    Работает но не работет как я быхотел. Дерево нужно отобразить в списке!

    Непойму почемувот эти значение не сравниваются в цикле IF но если $idr ставлю 16 то выводится ветвь запорожцев

    $idr =$tree[$i]['id'];//16= ЗАПАРОЖЦЫ
    $idpodrazdel=$tree[$i]['idradel'];



    [sql]DROP TABLE IF EXISTS `jos_vitrina_section`;
    CREATE TABLE `jos_vitrina_section` (
    `id` int(11) NOT NULL auto_increment,
    `idradel` int(1) NOT NULL default '0',
    `namesection` varchar(200) NOT NULL default '0',
    `publish` int(1) NOT NULL default '1',
    PRIMARY KEY (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=20 ;

    --
    -- Дамп данных таблицы `jos_vitrina_section`
    --

    INSERT INTO `jos_vitrina_section` VALUES (1, 0, 'Рыбалка', 1);
    INSERT INTO `jos_vitrina_section` VALUES (2, 0, 'Охота', 1);
    INSERT INTO `jos_vitrina_section` VALUES (3, 1, 'Удочки', 1);
    INSERT INTO `jos_vitrina_section` VALUES (5, 1, 'Леска', 1);
    INSERT INTO `jos_vitrina_section` VALUES (6, 1, 'Спиннинг', 1);
    INSERT INTO `jos_vitrina_section` VALUES (7, 1, 'Катушки', 1);
    INSERT INTO `jos_vitrina_section` VALUES (8, 1, 'Лодки', 1);
    INSERT INTO `jos_vitrina_section` VALUES (9, 2, 'Ружья', 1);
    INSERT INTO `jos_vitrina_section` VALUES (10, 2, 'Патроны', 1);
    INSERT INTO `jos_vitrina_section` VALUES (11, 2, 'Одежда охотника', 1);
    INSERT INTO `jos_vitrina_section` VALUES (12, 2, 'Палатки', 1);
    INSERT INTO `jos_vitrina_section` VALUES (13, 0, 'Машины', 1);
    INSERT INTO `jos_vitrina_section` VALUES (14, 13, 'жигули', 1);
    INSERT INTO `jos_vitrina_section` VALUES (15, 13, 'шеврале', 1);
    INSERT INTO `jos_vitrina_section` VALUES (16, 13, 'запарожец', 1);
    INSERT INTO `jos_vitrina_section` VALUES (17, 16, '1м запарожец', 1);
    INSERT INTO `jos_vitrina_section` VALUES (18, 16, '2 запарожец', 1);
    INSERT INTO `jos_vitrina_section` VALUES (19, 16, '3 запарожец', 1);[/sql]


    PHP:
    1. $hostName = "localhost";
    2.   $userName = "root";
    3.   $password = "";
    4.   $databaseName = "Joomla13";  if (!($link=mysql_connect($hostName,$userName,$password))) { printf("Ошибка при соединении с MySQL !\n"); exit(); }
    5.   if (!mysql_select_db($databaseName, $link)) { printf("Ошибка базы данных !"); exit(); }
    6.  
    7. /* * ID - Идентификатор ветки
    8.  * PID - Родительский ID (если pid=0 значит это самая первая ветка)
    9.  * FIELD1, FIELD2,... - Поля таблицы
    10.  * -----
    11.  *
    12.  * @return array
    13.  */
    14. function &make_tree()
    15. {   $tree = array();
    16.     $query = mysql_query('select * from jos_vitrina_section order by id');
    17.     if (! $query) return $tree;
    18.     $nodes = array();
    19.     $keys = array();
    20.     while (($node = mysql_fetch_assoc($query)))
    21.     {
    22.         //if ($node['childs'] === '1') //если есть поле определяющее наличие дочерних веток
    23.         //    $node['nodes'] = array();  //то добавляем к записи узел (массив дочерних веток) на данном этапе
    24.         $nodes[$node['id']] =& $node; //заполняем список веток записями из БД
    25.         $keys[] = $node['id']; //заполняем список ключей(ID)
    26.         unset($node);
    27.     }
    28.     mysql_free_result($query);
    29.     foreach ($keys as $key)
    30.     {
    31.         /**
    32.          * если нашли главную ветку(или одну из главных), то добавляем
    33.          * её в дерево
    34.          */
    35.         if ($nodes[$key]['idradel'] === '0')
    36.             $tree[] =& $nodes[$key];
    37.  
    38.         /**
    39.          * else находим родительскую ветку и добавляем текущую
    40.          * ветку к дочерним элементам родит.ветки.
    41.          */
    42.         else   {
    43.             if (isset($nodes[ $nodes[$key]['idradel'] ])) //на всякий случай, вдруг в базе есть потерянные ветки
    44.             {
    45.                 if (! isset($nodes[ $nodes[$key]['idradel'] ]['nodes'])) //если нет поля определяющего наличие дочерних веток
    46.                     $nodes[ $nodes[$key]['idradel'] ]['nodes'] = array(); //то добавляем к записи узел (массив дочерних веток) на данном этапе
    47.  
    48.                 $nodes[ $nodes[$key]['idradel'] ]['nodes'][] =& $nodes[$key];
    49.             }
    50.         }
    51.     }
    52.     return $tree;
    53. }
    54.  
    55. $tree =&make_tree();
    56. //echo $tree[2]['namesection']."<br>".$tree[2]['nodes'][2]['namesection'];//прямой запрос к значению в массиве
    57. /*  echo"<PRE>";
    58. print_r($tree);
    59. echo"</PRE>";
    60.  */
    61. $array_tree=array();//окнчательный массив
    62. $array_tovar=array();
    63. $array_tovar_tree=array();
    64. function tree_print(&$tree)
    65. {
    66. global $array_tovar, $array_tovar_tree;
    67.   //условие завершения рекурсии
    68.   //Условие, при котором функция никогда не вызывает сама себя
    69.   // - элемент массива не определен
    70.   // - элемент массива определен, но является пустым массивом
    71. if(empty($tree)) return;  //функция empty() - вернет ложь во всех нужных нам случаях:
    72.  //echo "<select>";
    73. for($i=0;$i<count($tree);$i++)
    74. {
    75. $idr =$tree[$i]['id'];//16=  ЗАПАРОЖЦЫ
    76. $idpodrazdel=$tree[$i]['idradel'];
    77. IF($idpodrazdel == 0)
    78. {
    79. array_push($array_tovar,"<option><a href= ".$tree[$i]['id'].">".$tree[$i]['namesection']."</a></option>");
    80. }else{//echo "ветки и подветки";
    81. IF($idpodrazdel == $idr) //ВОТ ТУТ НЕРАБОТЕТ  СРАВНЕИЕ НО ЕСЛИ ПОСТАВТЬ ПРИНУДИТЕЛЬНО 16 ТО ПОЯВИТСЯ ЕЩЕ ОДНА ВЕТВЬ
    82. {
    83. array_push($array_tovar,"<option><a href= ".$tree[$i]['id'].">------>(".$tree[$i]['id'].")".$tree[$i]['namesection']."</a></option>");
    84.  
    85. }else{
    86. array_push($array_tovar,"<option><a href= ".$tree[$i]['id'].">->(".$tree[$i]['id'].")".$tree[$i]['namesection']."</a></option>");
    87. }
    88.  
    89. }
    90. tree_print($tree[$i]['nodes']);
    91.   }
    92.  
    93. }
    94. tree_print($tree);
    95.  
    96. echo" <select class=\"\" name=\"idrazdel\"' >".implode(' ', $array_tovar)."</select> ";//<option value= \"0\" '> [ Раздел ]</option>
    97.  
    98.  
     
  10. Петр

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

    С нами с:
    20 мар 2006
    Сообщения:
    1.253
    Симпатии:
    0
    Адрес:
    Центр Вселенной
    Ох и простыня...
     
  11. nAgi

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

    С нами с:
    12 сен 2007
    Сообщения:
    43
    Симпатии:
    0
    выводит ввиде списка LI но я немогу его переделать под правильное выведение в список <select>

    PHP:
    1. function tree_print(&$tree)
    2. {
    3.   if(empty($tree)) return;
    4. echo "<ul>";
    5.   for($i=0;$i<count($tree);$i++)
    6.   {
    7.  echo "<li>".$tree[$i]['namesection'];
    8.    tree_print($tree[$i]['nodes']);
    9.     echo "</li>";
    10.   }
    11.   echo "</ul>";
    12. }
    13. tree_print($tree);
    14.  
    [/php]
     
  12. mantell

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

    С нами с:
    7 окт 2008
    Сообщения:
    125
    Симпатии:
    1
    Я когда в последний раз что-то подобное делал, всю структуру каталога(было 4 уровня) хранил в одной строке)
     
  13. nAgi

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

    С нами с:
    12 сен 2007
    Сообщения:
    43
    Симпатии:
    0
    я почти реализовал. скоро выложу рабочий вариант вывода в select
     
  14. nAgi

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

    С нами с:
    12 сен 2007
    Сообщения:
    43
    Симпатии:
    0
    Всё сделал теперь дерево отображается в списке с отступами вот рабочий код тем каму нужно будит в бущем

    Код (Text):
    1. <?
    2. $array_level=array();
    3. function tree_print(&$tree,$l,$id,$idradel,$padding)
    4. {
    5. global $array_level;
    6. if(empty($tree)) return;
    7. for($i=0;$i<count($tree);$i++)
    8. {
    9.  $styler="padding: 0px ".$padding."px;";//стиль CSS
    10.  IF($id = $idradel){ $styler="padding: 0px ".($padding+10)."px;"; }
    11.  IF($l == 0){
    12. //echo "<b>(".$tree[$i]['id'].")".$tree[$i]['namesection']."</b><br>";
    13. array_push($array_level,"<option style=\"".@$styler."\" value=\"".$tree[$i]['id']."\">".$tree[$i]['namesection']."</option>");
    14. }else{
    15. //echo"<i style=\"".@$styler."\">(".$tree[$i]['id'].")".$tree[$i]['namesection']."</i><br>";
    16. array_push($array_level,"<option style=\"".@$styler."\" value=\"".$tree[$i]['id']."\">".$tree[$i]['namesection']."</option>");
    17. }
    18. tree_print($tree[$i]['nodes'],1,$tree[$i]['id'],$tree[$i]['idradel'],($padding+10));
    19. /*  echo "<PRE>";
    20. print_r($tree[$i]['nodes']);//выводит масиив деревьев для информации
    21. echo "</PRE>";  */
    22. }
    23. }
    24. tree_print($tree,0,0,0,10);//запуск построения дерева
    25. ?>