递归菜单问题

时间:2011-03-08 11:46:49

标签: php recursion

我几个小时一直在弄乱递归而且无法正确使用它!

我希望我的菜单结构为:

<ul>
   <li> menu 1 <ul>
      <li> menu 1.1 <ul>
         <li> menu 1.1.1 </li>
      </ul>
   </ul>
<li> menu 2 </li>
<li> menu 3 <ul>
   <li> menu 3.1 </li>
</ul>
<li> menu 4 </li>
</ul>
</li>

但我不能说得对。

    print '<ul>';
    display_children(0, 0);
function display_children($parent, $level) {
   // retrieve all children of $parent

   $result = mysql_query('SELECT * FROM kategori WHERE parent="'.$parent.'";');

   while ($row = mysql_fetch_array($result)) {

       if($row['parent']!=0)
            print '<ul>';
       print '<li>';

       // indent and display the title of this child
       echo $row['navn']."\n";

       // call this function again to display this
       // child's children
       display_children($row['id'], $level+1);

   }

        print '</li>';
           print '</ul>';

就像现在一样,它会打印出正确的结构,但却会突然发现错位的<ul><il>

我的顶级菜单项为0作为父级(表示它们是绝对顶级),其子级的父母属性为父母属性。

我试图检查当前函数的运行情况(假设我们在菜单1.1.1)是否有父0,令我惊讶的是,我认为当前运行会有父母“菜单1.1”而不是“菜单1”

任何人都可以帮助我吗?我一直在盯着那段该死的代码,如果你能快速解决我如何获得这段代码片段来插入UL和IL的合适位置,我将非常感激!

提前致谢,Rasmus

3 个答案:

答案 0 :(得分:0)

某些伪代码可能会让您走上正轨:

function display_child_menus(parent_id) {

  menus = get_from_db_having_parent(parent_id)

  echo UL

  foreach (menus as menu) {

    echo LI

    echo menu->title

    children = get_menu_children(id)

    if (menu->has_children) {
      echo display_child_menus(menu->id)
    }

    echo /LI
  }

  echo /UL
}

echo display_child_menus(0)

请注意它是如何缩进的,以及它比您发布的代码更容易阅读。这有助于找到问题所在。

还要注意我没有显示数据的混合数据库内容。制作单独的函数(这里你可以看到函数get_from_db_having_parent)

答案 1 :(得分:0)

display_children可能不是最好的名字,像display_menu_level这样的内容可能更具描述性。想想它必须做什么:显示<ul>,然后是一些孩子,然后是</ul>。每个孩子都是<li>,“navn”文本,子菜单和</li>。只需在代码中反映该结构,如下所示:

function display_menu_level($parent, $level) {
    $results = mysql_query('SELECT * FROM kategori WHERE parent="'.$parent.'";');

    // Don't print an empty list ("<ul></ul>")
    if (mysql_num_rows($results) == 0) return;

    // Start the menu
    echo '<ul>';

    // Display children
    while ($row = mysql_fetch_array($result)) {
        // Start this child
        print '<li>';

        // indent and display the title of this child
        echo $row['navn']."\n";

        // call this function again to display this
        // child's children
        display_children($row['id'], $level+1);

        // Close this child
        print '</li>';
    }

    // Close the menu
    print '</ul>';
}

答案 2 :(得分:0)

您忘记添加开头<li>标记。

此外,不是直接打印,而是先将每个标签存储在一个数组中。

$parents = array();
While( parent exists )
{
  //  Query for children again
        $children = array();
         While(children exist)
         {
              $children[] = $row2[navn] ;
         }

        $parents[$row[navn]] = $children; 

        Unset($children);
}

现在使用foreach来显示:

Echo "<ul>"; 
Foreach ($parents as $k => $v)
{
     Echo "<li>".$k; 
     If (!empty($v))
    {
           Echo "<ul>"; 
           Foreach($v as $z)
           {
                 Echo "<li>".$z."</li>"; 
            }
            Echo "</ul>"; 
     }
     Echo "</li>"; 
}
Echo "</ul>";

我在手机上打字以赦免任何错误。我把它做成了一个维基,所以大家可以帮忙编辑它。顺便说一下,这是未经测试的。但不应该有任何错误。