За последние 24 часа нас посетили 70893 программиста и 1654 робота. Сейчас ищут 1303 программиста ...

Ветвящееся меню

Тема в разделе "Прочие вопросы по PHP", создана пользователем krow7, 17 окт 2011.

  1. krow7

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

    С нами с:
    12 авг 2009
    Сообщения:
    398
    Симпатии:
    0
    Адрес:
    из Азии
    Соорудил рекурсивную функцию для построения ветвящегося меню:
    PHP:
    1. <?php
    2. require('class/db.php');
    3. require_once('class/class.php');
    4. $time=new timer; // начинаем замер времени работы скрипта
    5. $db=new db('localhost', 'lalala', 'ololo', 'test', 1); // соединяемся с базой
    6. $db
    7.     ->execQuery('SET NAMES utf8'); // ну как всегда ;)
    8. function printMenu($level=1, $pid=0) // аргументы: уровень вложенности и родительский id
    9. {
    10.     global $db;
    11.     $result=$db
    12.         ->execQuery("SELECT `id`, `name`, `link` FROM `menu` WHERE `level`='{$level}' AND `parent`='{$pid}'");
    13.     if(mysqli_num_rows($result)==0)
    14.     {
    15.         return;
    16.     }
    17.     for($i=1; $i<$level; $i++)
    18.     {
    19.         echo '  ';
    20.     }
    21.     echo '<ul>'."\n";
    22.     while($arr=mysqli_fetch_assoc($result))
    23.     {
    24.         for($i=1; $i<$level; $i++)
    25.         {
    26.             echo '  ';
    27.         }
    28.         echo '  <li><a href="'.$arr['link'].'">'.$arr['name'].'</a></li>'."\n";
    29.         printMenu($level+1, $arr['id']);
    30.     }
    31.     for($i=1; $i<$level; $i++)
    32.     {
    33.         echo '  ';
    34.     }
    35.     echo '</ul>'."\n";
    36. }
    37. printMenu(); // запускаем функцию
    38. echo '<hr align="left" width="500"><br>';
    39. echo $db->getQueryCount(); // выводим число sql-запросов за время работы
    40. $db->close();
    41. echo '<br>'.$time->end_timer(); // выводим время работы скрипта
    Структура таблицы:
    [sql]CREATE TABLE `menu` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) DEFAULT NULL,
    `link` varchar(255) CHARACTER SET cp1251 DEFAULT NULL,
    `level` smallint(6) DEFAULT NULL,
    `parent` smallint(6) DEFAULT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=utf8[/sql]
    name - то что будет отображено
    link - ссылка
    level - на каком уровне вложенности находится элемент
    parent - родительский id (у первого уровня вложенности parent=0)
    [​IMG]
    Имеется в общей сумме 13 элементов меню, выполняется всего 15 запросов (1 запрос - это SET NAMES). Время работы - 0.52645897865295 (0.5 уходит на подключение, не знаю почему так долго подключается, поднимал тут тему).

    Жду Ваших предложений и дополнений. В частности, можно ли сократить количество SQL-запросов? Ответы типа: "погугли вот такую вот систему для вывода менюшек" не котируются, т.к. хотелось самому попробовать.
     
  2. runner

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

    С нами с:
    16 апр 2010
    Сообщения:
    343
    Симпатии:
    1
    Адрес:
    Ташкент
    Для небольших деревьев более быстрый вариант одним запросом получить все данные и затем просто их обработать
     
  3. Михаил

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

    С нами с:
    12 июл 2009
    Сообщения:
    545
    Симпатии:
    0
    Адрес:
    Bielarus
    global $db;
    оно разве нужно здесь?
    безполезняк
    Код (Text):
    1. for($i=1; $i<$level; $i++)
    2.      {
    3.          echo '    ';
    4.      }
    лучше
    Код (Text):
    1.  
    2. echo str_repeat("    ", $level);
    Зачем mysqli_fetch_assoc, если есть mysqli_fetch_all вроде как.
    И опять же сочетание процедруного стиля и объектного не кошерно. Переписать. и да сделай всё в один/два запроса, как runner говорил
     
  4. Volt(220)

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

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
  5. udodirc

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

    С нами с:
    14 мар 2008
    Сообщения:
    111
    Симпатии:
    0
    Маленькие деревья можно обрабатывать рекурсивно, а вот большие лучше использовать Nested Seats.
     
  6. krow7

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

    С нами с:
    12 авг 2009
    Сообщения:
    398
    Симпатии:
    0
    Адрес:
    из Азии
    всех послушал, интересно, буду работать ;)