使用递归的动态菜单树

时间:2015-12-10 07:06:38

标签: php recursion

我需要PHP中的递归帮助。我需要从JSON创建文件夹结构。这就是它的样子,

{  
   "parent":{  
      "url":"parent.html",
      "name":"Parent",
      "children":[  
         {  
            "type":"folder",
            "name":"Folder 1",
            "url":"folder1.html",
            "children":[  
               {  
                  "type":"file",
                  "name":"File 1",
                  "url":"folder1-file1.html",
                  "children":[  

                  ]
               },
               {  
                  "type":"file",
                  "name":"File 2",
                  "url":"folder1-file2.html",
                  "children":[  

                  ]
               },
               {  
                  "type":"file",
                  "name":"File 2",
                  "url":"folder1-file3.html",
                  "children":[  

                  ]
               }
            ]
         },
         {  
            "type":"folder",
            "name":"Folder 2",
            "url":"folder2.html",
            "children":[  

            ]
         },
         {  
            "type":"folder",
            "name":"Folder 3",
            "url":"folder3.html",
            "children":[  
               {  
                  "type":"file",
                  "name":"Folder3 File1",
                  "url":"folder3-file1",
                  "children":[  

                  ]
               },
               {  
                  "type":"folder",
                  "name":"Folder3 Folder1",
                  "url":"folder3-file1",
                  "children":[  
                     {  
                        "type":"folder",
                        "name":"Folder3 Folder1 Folder1",
                        "url":"folder3-folder1-folder1",
                        "children":[  
                           {  
                              "type":"file",
                              "name":"Folder3 Folder1 Folder1 File1",
                              "url":"folder3-folder1-folder1-file1",
                              "children":[  

                              ]
                           },
                           {  
                              "type":"file",
                              "name":"Folder3 Folder1 Folder1 File2",
                              "url":"folder3-folder1-folder1-file2",
                              "children":[  

                              ]
                           }
                        ]
                     }
                  ]
               }
            ]
         }
      ]
   }
}

如果有文件夹,则应创建一个新的<ul>,其中folder类的名称位于<a>标记内,如果有任何类型为file的子项,则应该在<li>内创建名称为<a>的新<ul class="folder"> <li> <a>Parent</a> <ul class="folder"> <li> <a>Folder 1</a> <ul class="folder"> <li> <a>File 1</a> </li> <li> <a>File 2</a> </li> <li> <a>File 2</a> </li> </ul> </li> <li> <a>Folder 2</a> </li> <li> <a>Folder 3</a> <ul class="folder"> <li> <a>Folder3 File1</a> </li> <li> <a>Folder3 Folder1</a> <ul class="folder"> <li> <a>Folder3 Folder1 Folder1</a> <ul class="folder"> <li> <a>Folder3 Folder1 Folder1 File1</a> </li> <li> <a>Folder3 Folder1 Folder1 File2</a> </li> </ul> </li> </ul> </li> </ul> </li> </ul> </li> </ul> ,依此类推。

private function menuBuilder($menu_array, $is_sub = false)
{
    $attr = (!$is_sub) ? ' id="menu"' : ' class="submenu"';
    $menu = "<ul$attr>";

    $sub = '';
    foreach ($menu_array as $child) {
        foreach ($child as $key => $val) {
            if (is_array($val)) {
                $sub = $this->menuBuilder($val, true);
            } else {
                $sub = null;
                $$key = $val;
            }
        }

        $menu .= "<li><a>".$child['name']."</a>$sub</li>";
        unset($url, $display, $sub);

    }
    return $menu . "</ul>";
}

即使没有孩子,我已经拥有了一个循环功能,

MovementScript

请帮助优化这一点。

3 个答案:

答案 0 :(得分:1)

我在正常的PHP上做过,希望它会有所帮助

function add_list($folder, &$list){
        $list .= '<li>';
            $list .= '<a>'.$folder['name'].'</a>';
            if(count($folder['children']) > 0)
            {
                $list .= '<ul class="folder">';
                foreach($folder['children'] as $child)
                    add_list($child, $list);
                $list .= '</ul>';
            }
        $list .= '</li>';

}

$array = json_decode($json,True);

$list = '<ul class="folder">';
foreach($array as $folder)
    add_list($folder, $list);
$list .= '</ul>';

echo $list;

答案 1 :(得分:0)

这是我最后使用的,

function menuBuilder($menu_array, $is_sub = false)
{
    if(!$is_sub) {
        $menu = '<ul id="side-menu" class="nav"><li class="top-li"></li>';
    } else {
        $menu = '<ul class="nav side-submenu">';
    }

    $sub = '';
    foreach ($menu_array as $child) {
        foreach ($child as $key => $val) {
            if (is_array($val)) {
                $sub = menuBuilder($val, true);
            } else {
                $sub = null;
                $$key = $val;
            }
        }

        $menu .= "<li>".((trim($child['name'])!=null)?("<a>".$child['name']."</a>"):"")."$sub</li>";
        unset($url, $display, $sub);

    }
    return $menu . "</ul>";
}

$array = json_decode($json, true);
echo $list =  menuBuilder($array['data']['parentNode']['children']);

答案 2 :(得分:-1)

以下是递归的逻辑示例,您必须完成内部代码

function buildMenu($items){

  $menuHtml = "";

  foreach($items as $item){
     if( $item['type'] == 'folder'){

       $menuHtml .= "<ul><a>...</a>";
       if( !empty($item['children']) ){
          $menuHtml .= buildMenu($item['children']);
       }
       $menuHtml .= "</ul>";

     }elseif( $item['type'] == 'file'){

       $menuHtml .= "<li><a>...</a></li>";
       if( !empty($item['children']) ){
          $menuHtml .= buildMenu($item['children']);
       }
     }
  }

  return $menuHtml;
}

// Where $menu is your dumped array
$resultHTML = buildMenu($menu['children']);