Многоуровневого меню - мой вариант

DenVeroid

Новичок
Многоуровневого меню - мой вариант

Здравствуйте, решил написать скрипт вывода разделов, с выпадающей веткой текущего раздела. Реализовал таким образом.

Рекурсивная функция
PHP:
<?php
function ShowTree($ParentID, $lvl) {
    global $tree;
    if (!isset($tree[$ParentID])) return;
    $indent = str_repeat('  ', $lvl);
    echo $indent."<ul>\n";
    foreach($tree[$ParentID] as $item) {
         echo $indent.'  <li><a href="?ID='.$item["id"]."\">".$item["name"]."</a></li>\n";
        ShowTree($item["id"], $lvl+1);
    }
    echo($indent."</ul>\n");
}
?>

Здесь получаем список разделов
PHP:
<?php
$tree = array();

<?php $sql_result = $db->q("SELECT `id`,`name`,`parent` FROM " . PREFIX . "cat  where parent IN(0,1,2,7,54) ");

while($row = $db->mysql_assoc($sql_result)){
   $tree[$row['parent']][] = $row;
}

ShowTree(0, 0);
?>
в запросе мы указываем IN(0,1,2,7,54) , где 0,1,2,7,54 номера Parent, сделал для того чтобы не помещать весь список из таблицы, а ограничился только теми разделами, которые нужно вывести.

Таким образом мы не забиваем массив $tree всеми подразделами что находятся в данной таблице, что могло бы случится если допустим было 500-1000 подразделов, массив просто был бы огромным.

Недостаток только в одном, - вычислить значения Parent`а для текущей ветки.

Ниже приведу несколько примеров выбора разделов


PHP:
[b]при запросе[/b]
<?php $sql_result = $db->q("SELECT `id`,`name`,`parent` FROM " . PREFIX . "cat where parent IN(0,1,3,13) "); ?>

[b]получаем[/b]

<ul>
  <li><a href="?ID=1">Россия</a></li>
  <ul>
    <li><a href="?ID=2">Москва</a></li>
    <li><a href="?ID=3">Санкт-Питербург</a></li>
    <ul>
      <li><a href="?ID=9">Невский</a></li>

      <li><a href="?ID=10">Петроградский</a></li>
      <li><a href="?ID=11">Авиамоторный</a></li>
      <li><a href="?ID=13">Автово</a></li>
    </ul>
    <li><a href="?ID=4">Новосибирск</a></li>
    <li><a href="?ID=5">Кемерово</a></li>

    <li><a href="?ID=42">Томск</a></li>
    <li><a href="?ID=41">Омск</a></li>
  </ul>
  <li><a href="?ID=14">Германия</a></li>
  <li><a href="?ID=15">Австрия</a></li>
  <li><a href="?ID=16">США</a></li>

  <li><a href="?ID=58">Япония</a></li>
  <li><a href="?ID=59">Франция</a></li>
  <li><a href="?ID=60">Банког</a></li>
  <li><a href="?ID=61">Грузия</a></li>
</ul>
PHP:
[b]при запросе[/b]
<?php $sql_result = $db->q("SELECT `id`,`name`,`parent` FROM " . PREFIX . "cat where parent IN(0,15,62) "); ?>

[b]получаем[/b]

<ul>
  <li><a href="?ID=1">Россия</a></li>
  <li><a href="?ID=14">Германия</a></li>
  <li><a href="?ID=15">Австрия</a></li>
  <ul>
    <li><a href="?ID=62">Сочи</a></li>
  </ul>

  <li><a href="?ID=16">США</a></li>
  <li><a href="?ID=58">Япония</a></li>
  <li><a href="?ID=59">Франция</a></li>
  <li><a href="?ID=60">Банког</a></li>
  <li><a href="?ID=61">Грузия</a></li>
</ul>







PHP:
[b]при запросе[/b]
<?php $sql_result = $db->q("SELECT `id`,`name`,`parent` FROM " . PREFIX . "cat where parent IN(0,1,2,7,54) "); ?>

[b]получаем[/b]

<ul>
  <li><a href="?ID=1">Россия</a></li>
  <ul>
    <li><a href="?ID=2">Москва</a></li>
    <ul>
      <li><a href="?ID=6">Химки</a></li>
      <li><a href="?ID=7">Железнодорожный</a></li>

      <ul>
        <li><a href="?ID=54">Посёлок</a></li>
      </ul>
      <li><a href="?ID=8">Обнинск</a></li>
    </ul>
    <li><a href="?ID=3">Санкт-Питербург</a></li>
    <li><a href="?ID=4">Новосибирск</a></li>

    <li><a href="?ID=5">Кемерово</a></li>
    <li><a href="?ID=42">Томск</a></li>
    <li><a href="?ID=41">Омск</a></li>
  </ul>
  <li><a href="?ID=14">Германия</a></li>
  <li><a href="?ID=15">Австрия</a></li>

  <li><a href="?ID=16">США</a></li>
  <li><a href="?ID=58">Япония</a></li>
  <li><a href="?ID=59">Франция</a></li>
  <li><a href="?ID=60">Банког</a></li>
  <li><a href="?ID=61">Грузия</a></li>
</ul>
На всё про всё, уходит всего один запрос, при этом массив совсем небольшой, содержит только то что нужно вывести. И глубина вложенности при этом также может быть любой.

Всё это работает но только с поставлением вручную Parent`а хотелось бы чтобы автоматически.

Единственное что напрягает, это с вычислением Parent`а, как его определить чтобы не делать несколько запросов, Пока в голову пришла одна мысль создать дополнительную таблицу, где будят содержатся значения Parent`а примерно так

ID | var
1 | 0,1,2,7,54
2 | 0,15,62
3 | 0,1,3,13


в этом случаи не удобно будет то что при каждом изменении раздела, создании, перемещении,удалении нужно править эту таблицу.

Хотел спросить ваше мнение, как насчёт этой идеи вывода разделов, и может есть какие нибудь идеи по вычислению Parent с одним запросом?

ЗЫ: немного уточню насчёт отдельной таблицы, чтобы было понятнее, сделана она для того чтобы можно было обратится всего одним запросом для вычисления Parent`тов. Т.к если мы по пытаемся вычислить через основную таблицу, у нас как я полагаю с одним запросом не получится, нужно будет пройтись циклом от конечного раздела до корня (Parent=0), что получится запросов столько же сколько и уровней вложностей.

да и как этот вариант, какие могут быть не приятные последствия?
 

DenVeroid

Новичок
а как насчёт моего варианта, на сколько он плох? и чем другие лучше?
 

zerkms

TDD infected
Команда форума
DenVeroid
Всё это работает но только с поставлением вручную Parent`а хотелось бы чтобы автоматически.
на сколько он плох? и чем другие лучше?
твой вариант не работает. другие работают. этим они лучше.
 

DenVeroid

Новичок
работает, только если указывать вручную в запрос значения родительских ID в запросе, если заранее о них знаеш

единственное я ещё не дописал код, чтобы можно было сохранять эти значения в отдельной таблице, решил предварительно поинтересоваться данным вариантом

в моём варианте массив получает не всю таблицу записей, как это делается обычно, а только те записи которые нужно вывести, тем самым нагрузка для скрипта будет меньше т.к массив совсем небольшой. Функция рекурсии нагружается меньше т.к объём массива небольшой
 
Сверху