php和mysql目录样式数据库中的子菜单

php和mysql目录样式数据库中的子菜单,php,mysql,list,drop-down-menu,nested-loops,Php,Mysql,List,Drop Down Menu,Nested Loops,我一直试图通过php和mysql在每个主菜单上创建一个包含子菜单的菜单,然后在每个子菜单上创建子菜单。我觉得我已经快到了,但我对php和mysql还不熟悉,所以我来这里寻求你们的帮助。 我已经搜索了几个小时的答案,我找到了下拉菜单的例子,但没有一个像这样 不确定如何在此处添加sql数据库,但如果请求,将尝试添加 到目前为止,我的php代码如下 $result = mysqli_query($link, 'SELECT * FROM library WHERE parent_id =' . $pa

我一直试图通过php和mysql在每个主菜单上创建一个包含子菜单的菜单,然后在每个子菜单上创建子菜单。我觉得我已经快到了,但我对php和mysql还不熟悉,所以我来这里寻求你们的帮助。 我已经搜索了几个小时的答案,我找到了下拉菜单的例子,但没有一个像这样

不确定如何在此处添加sql数据库,但如果请求,将尝试添加

到目前为止,我的php代码如下

$result = mysqli_query($link, 'SELECT * FROM library WHERE parent_id =' . $parent_id = 0);

$subResult = mysqli_query($link, 'SELECT * FROM library WHERE parent_id >'. $parent_id);
    if(mysqli_num_rows($result) > 0) {
                echo '<ul class="nav list">';

                        while($row = mysqli_fetch_array($result))
                        {
                            echo '<li class="nav-item">'. '<a href="#">'.$row['mainfolder'] .'</a>'.
                              '<ul class="dropdown-content nav">';
                            while($sub = mysqli_fetch_array($subResult))
                            {
                                if($row['id']===$sub['parent_id'])
                                {

                                        echo $sub['parent_id'];

                                    $submenuItems = mysqli_query($link, 'SELECT mainfolder FROM library WHERE parent_id ='. $sub['parent_id']);
                                    $items = mysqli_fetch_array($submenuItems);
                                    foreach ($items as $eachItem){
                                       echo' <li class="submenu">'.'<a class="sub" href="#">'.htmlspecialchars($eachItem, ENT_QUOTES, 'UTF-8').'</li>'.'</a>'.'</ul>';
                                    }
                                }
                            }

                        }
                            echo '</ul>'.'</li>'; 


                echo '</ul>';
            }
$result=mysqli\u query($link,“SELECT*FROM library WHERE parent\u id=”。$parent\u id=0);
$subResult=mysqli_query($parent_id>,链接“从父库中选择*”);
如果(mysqli_num_行($result)>0){
echo'
    ; while($row=mysqli\u fetch\u数组($result)) { echo'
  • '.'。 “
      ”; 而($sub=mysqli\u fetch\u数组($subResult)) { 如果($row['id']==$sub['parent\u id'])) { echo$sub['parent_id']; $subnumitems=mysqli_query($link,'selectmainfolder FROM library WHERE parent_id='。$sub['parent_id']); $items=mysqli\u fetch\u数组($subnumitems); foreach($eachItems作为$eachItem){ 回显“
    ”; } } } } 回音“
”、“”; 回声“”; }
因为您的要求很好,而且因为我喜欢递归函数的挑战,所以我决定继续帮助您

我最初的回答有点失控,所以我把它清理干净了。我还做了大量的调试,并修复了我在原始帖子中发现的一些“bug”

echo "<pre>"; //preserve whitespace

//I mocked up some arrays ('canned data') to make things easier to show and test
//order of the parents matter ( should be in the order left to right of the menu )
$parents = [
   ['id' => 1, 'title' => 'item1', 'link' => 'http://www.example.com/item1', 'parent_id' => 0], 
   ['id' => 8, 'title' => 'item8', 'link' => 'http://www.example.com/item8', 'parent_id' => 0],
];

var_export( $parents );
echo "\n\n";

//you can order children any way you want, they will still be grouped under the right parent
$children = [
    ['id' => 2, 'title' => 'item2', 'link' => 'http://www.example.com/item2', 'parent_id' => 1],        
    ['id' => 3, 'title' => 'item3', 'link' => 'http://www.example.com/item3', 'parent_id' => 2],
    ['id' => 4, 'title' => 'item4', 'link' => 'http://www.example.com/item4', 'parent_id' => 1], //not ordered
    ['id' => 5, 'title' => 'item5', 'link' => 'http://www.example.com/item5', 'parent_id' => 2, "target" => null, "css_class" => null],
    ['id' => 6, 'title' => 'item6', 'link' => 'http://www.example.com/item6', 'parent_id' => 1, "target" => "_blank"], 
    ['id' => 7, 'title' => 'item7', 'link' => 'http://www.example.com/item7', 'parent_id' => 8, "css_class"=>"test"],  
];

var_export($children);
echo "\n\n";

$lv = 1;

$html = "<ul class=\"menu menu_lv0\" >\n";

foreach( $parents AS &$parent ){
    $html = buildMenuTree( $parent, $children, $html, $lv, $lv );   //pass by refrence so no return needed
}

$html .= "</ul>\n";

var_export( $parents );
echo "\n\n";

echo htmlspecialchars( $html )."\n\n"; //htmlspecialchars for display reasons


//=========================================
//            DEFINE FUNCTION
//=========================================

//$parent is passed by refrence
function buildMenuTree( &$parent, $children, $html='', $lv=0, $indent=0 ){

    if( $lv == 1 || $lv == 2) $mode = true;

    if( !$children ) return;
    reset( $children ); //reset the array

    $t0 = getIndent( $indent );
    $t1 = getIndent( ($indent+1) );

    //css class for menu item
    $css_class = (isset($parent['css_class']) && $parent['css_class']) ? " {$parent['css_class']}" : "";
    //link target
    $target = (isset($parent['target']) &&  $parent['target']) ? "target=\"{$parent['target']}\" " : "";

    $id = $parent['id'];

    $html .= "{$t0}<li id=\"menu_item_{$id}\" class=\"menu_item item_lv{$lv}{$css_class}\">\n";
    $html .= "{$t1}<a class=\"menu_link\" href=\"{$parent['link']}\" {$target}>{$parent['title']}</a>";

    while( false !== ( $child = current( $children ) ) ){           
        //if the parents id, matches the childs parent id, then add the current child
        //as a child of parent and check it ( current child ) for any children it may have
        // add  if( ... && $limit == $lv) and pass in a $limit param to the function to limit the depth
        if( $parent['id'] == $child['parent_id'] ){
            $key = key( $children );
            //remove - to reduce array and our processing time, we can remove the current item
            //also the current item is the parent in the recusive function and therefore we
            //know it cannot be a child of itself and we wont need it in that branch
            unset( $children[$key] ); 

            //make a recursive call ( call this method again
            //&$parent, $children, $html='', $lv=1, $indent=1
            $r_html = buildMenuTree($child, $children, "", ($lv + 1), ($indent+2));

            //creante the children array if not exists
            if( !isset( $parent['children'] ) ){
                $parent['children'] = []; 

                $html .= "\n{$t1}<ul class=\"sub_menu menu_lv{$lv} parent_{$parent['id']}\" >\n";
                $html .= $r_html;
            }else{
                $html .= $r_html;
            }

            ///store the child
            $parent['children'][] = $child;

        }else{
            $next = next( $children );

        };
    }

    if( !isset( $parent['children'] ) )
       $html .= "\n";
    else 
       $html .= "{$t1}</ul>\n";

    $html .= "{$t0}</li>\n";

    return $html;
}

function getIndent( $indent, $pad = " " ){
    return str_pad("", ( $indent * 4 ), $pad);
}

echo "</pre>";
HTML

菜单
  • 我冒昧地添加了一些我认为是通常实现的导航菜单的特性。

    • CSS类,如果一行包含
      $row['CSS_Class']
      ,则
    • 会将其值添加到它的类中,您可以将其设置为
      false | null
      或干脆不包含它
    • 目标,如果项目包含
      $row['Target']


      祝你好运,祝你愉快

      您需要一个树结构和一个递归的“walker”类型函数来正确嵌套对象。查找
      嵌套集
      邻接列表
      物化路径
      层次化数据结构。一旦您获得层次结构中的数据,那么您将需要一个函数(可能是递归函数)来构建
      ul>li
      集,然后是一些适当的CSS,这不是世界上最容易做到的事情。。。lolparent\u id=$parent\u id=0-这一点你都不觉得奇怪?我觉得很好,
      “。。。。父项_id='。($parent_id=0)
      它可以工作。。。我认为这是没有意义的,因为在任何情况下,执行两个简单的查询都不会得到多层嵌套树。我所有的主菜单项都有parent_id=0,所以我只是简单地选择它们。如果我能让大家看看桌子,那就容易多了。嗨,谢谢你,真的很感谢你的努力。我还没有让它工作,但这是一个进步。在逐行将其添加到我的代码之后。我觉得我添加的数据是错误的,因为当我在传入任何函数之前回显$parents数组时,我得到了以下输出:Array11Item1 Item100当在gettreecursive()之前的foreach函数中使用echo with时,我得到了以下结果:array(0=>1',id=>1',1=>Item 1',mainfolder'=>Item 1',2=>0',parent\u id'=>0',)“”以及此im收到错误:非法字符串偏移量“id”和“parent_id”。因此,我已通过从元素中删除引号和[]修复了非法偏移量问题。不太清楚我为什么要这么做。但是现在html上没有显示任何内容。不过没有警告。我想我更希望你对这个数组的第一个注释是一条记录,当你想要很多记录时,你应该有
      [0=>['id'=>1,…]
      而且你没有在你的查询中设置fetch模式,所以你得到了一个数字数组和一个你想要使用的关联数组
      mysqli\u fetch\u assoc()
      而不是
      mysqli\u fetch\u array()
      $parent = array (
        0 => 
        array (
          'id' => 1,
          'title' => 'item1',
          'link' => 'http://www.example.com/item1',
          'parent_id' => 0,
          'children' => 
          array (
            0 => 
            array (
              'id' => 2,
              'title' => 'item2',
              'link' => 'http://www.example.com/item2',
              'parent_id' => 1,
              'children' => 
              array (
                0 => 
                array (
                  'id' => 3,
                  'title' => 'item3',
                  'link' => 'http://www.example.com/item3',
                  'parent_id' => 2,
                ),
                1 => 
                array (
                  'id' => 5,
                  'title' => 'item5',
                  'link' => 'http://www.example.com/item5',
                  'parent_id' => 2,
                  'target' => NULL,
                  'css_class' => NULL,
                ),
              ),
            ),
            1 => 
            array (
              'id' => 4,
              'title' => 'item4',
              'link' => 'http://www.example.com/item4',
              'parent_id' => 1,
            ),
            2 => 
            array (
              'id' => 6,
              'title' => 'item6',
              'link' => 'http://www.example.com/item6',
              'parent_id' => 1,
              'target' => '_blank',
            ),
          ),
        ),
        1 => 
        array (
          'id' => 8,
          'title' => 'item8',
          'link' => 'http://www.example.com/item8',
          'parent_id' => 0,
          'children' => 
          array (
            0 => 
            array (
              'id' => 7,
              'title' => 'item7',
              'link' => 'http://www.example.com/item7',
              'parent_id' => 8,
              'css_class' => 'test',
            ),
          ),
        ),
      )
      
      <ul class="menu menu_lv0" >
          <li id="menu_item_1" class="menu_item item_lv1">
              <a class="menu_link" href="http://www.example.com/item1" >item1</a>
              <ul class="sub_menu menu_lv1 parent_1" >
                  <li id="menu_item_2" class="menu_item item_lv2">
                      <a class="menu_link" href="http://www.example.com/item2" >item2</a>
                      <ul class="sub_menu menu_lv2 parent_2" >
                          <li id="menu_item_3" class="menu_item item_lv3">
                              <a class="menu_link" href="http://www.example.com/item3" >item3</a>
                          </li>
                          <li id="menu_item_5" class="menu_item item_lv3">
                              <a class="menu_link" href="http://www.example.com/item5" >item5</a>
                          </li>
                      </ul>
                  </li>
                  <li id="menu_item_4" class="menu_item item_lv2">
                      <a class="menu_link" href="http://www.example.com/item4" >item4</a>
                  </li>
                  <li id="menu_item_6" class="menu_item item_lv2">
                      <a class="menu_link" href="http://www.example.com/item6" target="_blank" >item6</a>
                  </li>
              </ul>
          </li>
          <li id="menu_item_8" class="menu_item item_lv1">
              <a class="menu_link" href="http://www.example.com/item8" >item8</a>
              <ul class="sub_menu menu_lv1 parent_8" >
                  <li id="menu_item_7" class="menu_item item_lv2 test">
                      <a class="menu_link" href="http://www.example.com/item7" >item7</a>
                  </li>
              </ul>
          </li>
      </ul>