MySQL DB управляемая функция генератора меню - PullRequest
0 голосов
/ 07 октября 2011

Недавно я написал рекурсивную функцию PHP, которая генерирует навигацию по сайту на основе структуры типа «родители-потомки», как это

<ul>
  <li>parent
     <li>child</li>
  </li>
</ul>

Код выглядит так

function generateMenu($parent, $level, $db){
  $q = $db->query("select id, name FROM menu WHERE parent = '$parent'");

  if($level > 0 && $q->num_rows > 0) echo "\n<ul>\n";

   while($row=$q->fetch_object()){
      echo "<li>";
      echo '<a href="?page=' .$page. '">' . $row->name . '</a>';
      //display this level's children
      generateMenu($row->id, $level++, $menu, $db);
      echo "</li>\n\n";
    }

    if($level > 0 &&  $q->num_rows > 0) echo "</ul>\n";
}

Часть кода выше просто повторяет структуру <ul><li> (как в приведенном выше примере) из таблицы БД.

Теперь возникает вопрос, как создать меню навигации, как на этом сайте?

Пожалуйста, посмотрите на левую боковую панель.

http://www.smithsdetection.com/continuous_vapour_sampling.php

Теперь я думаю, что:

  1. Прежде всего, мы должны повторить все родители
  2. Функция должна получить идентификатор текущей страницы в качестве входного значения (например, $ current)
  3. Функция должна отображать текущий уровень страниц

Я не могу понять, как изменить мою функцию, чтобы получить результат, как на данном сайте. Пожалуйста, помогите.

КСТАТИ

Моя таблица БД выглядит так

enter image description here

ПРИМЕЧАНИЕ Пожалуйста, не публикуйте ответы о дырах в SQL-инъекциях, я уже позаботился о них: проверка с помощью in_array (если переменная указана в массиве имен столбцов) и прохождение через real_escape.

Ответы [ 2 ]

3 голосов
/ 07 октября 2011

Посмотрите на это: http://www.ferdychristant.com/blog/archive/DOMM-7QJPM7

Вы должны попытаться получить всю иерархию одним запросом, чтобы решить проблему с производительностью.

2 голосов
/ 07 октября 2011

Предполагается, что идентификатор текущей страницы находится в переменной $current, а $ db - это открытое соединение с MySQLi DB:

// first get your current page's path back to root:
// $stack will be a stack of menus to show
$stack = array();

// always expand current menu:
$stack[] = $current;

// now starting at $current, we go through the `menu` table adding each parent
// menu id to the $stack until we get to 0:
$i = $current;
while ( $i > 0 ) {
  // get parent of $i
  $query = sprintf('SELECT `parent` FROM `menu` WHERE id=%d LIMIT 1', $i);
  $result = $db->query($query);

  if (!$result) {
    // do error handling here
  }

  $row = $result->fetch_assoc();

  // save parent id into $i...
  $i = $row['parent'];

  // ...and push it onto $stack:
  $stack[] = $i;
}

/**
 * @param int $parent the parent ID of the menu to draw.
 * @param array $stack the stack of ids that need to be expanded
 * @param string $indent string for pretty-printing html
 * @param MySQLi $db Open db connection
 */
function generateMenu($parent, $stack, $indent, $db){

  // $next is the next menu id that needs expanding
  $next = array_pop($stack);

  $query = sprintf('SELECT `id`, `name` FROM `menu` WHERE `parent`=%d', $parent);

  $result = $db->query($query);

  if ( ! $result ) {
    // do error handling here
  }

  if ($result->num_rows > 0) {
    echo "\n$indent<ul>\n";

    while($row = $result->fetch_object()){
      echo "$indent  <li>\n";
      echo "$indent    <a href=\"?page={$row->id}\">{$row->name}</a>\n";

      //display this level's children, if it's the $next menu to need to be drawn:
      if ($row->id == $next)
        generateMenu($next, $stack, "$indent    ", $db);

      echo "$indent  </li>\n\n";
    }
    echo "$indent</ul>\n";
  }
  $result->free();
}

$first = array_pop($stack); // should always be 0
generateMenu($first, $stack, '', $db);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...