【问题标题】:Dynamic menu tree using recursion使用递归的动态菜单树
【发布时间】:2016-01-05 21:13:41
【问题描述】:

我需要有关 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>";
}

请帮忙优化一下。

【问题讨论】:

  • 你试过什么?你得到什么具体的错误?我相信您知道,但让我提醒您,StackOverflow 用户不会为您编写代码,我们会帮助解决具体问题。
  • @T3H40 好吧,我知道,我会忘记添加该代码,我现在正在添加:)
  • 太棒了。请不要忘记描述究竟是什么不工作:)

标签: php recursion


【解决方案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;

【讨论】:

    【解决方案2】:

    这是我最后用的,

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

    【讨论】:

      【解决方案3】:

      这是递归的逻辑示例,您只需完成内部代码

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

      【讨论】:

      • $menuHtml 应该是功能外的,所以当你再次请求该功能时不会将其清除回来
      • @FahedAlkaabi 我刚刚在第一次发帖后添加了它你没看到吗?
      • if(isset($item['children'])) 它总是设置,尝试检查是否为空
      • 作为@FahedAlkaabi,它似乎总是空的,所以没有生成任何东西:(
      猜你喜欢
      • 2019-01-25
      • 1970-01-01
      • 2013-03-21
      • 2013-03-12
      • 1970-01-01
      • 1970-01-01
      • 2017-12-31
      • 1970-01-01
      • 2012-06-02
      相关资源
      最近更新 更多