2011-03-08 61 views
0

我一直在用递归搞乱几个小时,只是不能正确地做对!递归菜单问题

我希望我的菜单结构为:

<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>'; 

,因为它是现在,它打印正确的结构,但poops出missplaced <ul><il>

一个crapton我的顶级菜单项已经0父(以表明他们是绝对顶部)其子女的父母身份为父母。

我试着检查函数的当前运行(可以说我们在菜单1.1.1)有父母0,这令我惊讶,是真实的,因为我会认为当前运行的会有父母“菜单1.1”而不是“菜单1”

任何一个能够帮助我在这里?我一直在盯着waaay的那段该死的代码,如果你能快速修复这个代码片段,以便插入UL和IL,我将非常感激!

由于提前,拉斯穆斯

回答

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>'; 
} 
+0

正是我想到的,谢谢! – Rasmus 2011-03-08 13:14:26

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)

+0

你是对的,我需要对如何构建我的代码以便维护和扩展有一些想法。我会牢记这一点,感谢您的意见! – Rasmus 2011-03-08 13:16:36

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>"; 

我打一个电话就这么原谅任何错误。我做了这个维基,所以人们可以帮助编辑它。顺便说一句,这是未经测试的。但不应该有任何错误。

+0

没有必要标记您的帖子社区Wiki只是为了让其他人可以编辑 - 甚至匿名用户也可以建议修改(http:// stackoverflow。com/faq#login) - 他们建议的编辑会通过编辑审阅过程被接受或拒绝。并且[拥有2000个信誉点的用户可以无延迟地编辑](http://stackoverflow.com/privileges/edit)。 :) – sarnold 2011-07-11 21:54:41

+0

@sarnold。感谢您的提升。这是我的第一个答案。我现在更聪明了。 – frostymarvelous 2011-07-12 06:32:24