2015-12-10 5 views
0

Мне нужна помощь с рекурсией в 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>"; 
} 

Пожалуйста, помогите оптимизировать это.

+0

Что вы пробовали? Какая конкретная ошибка вы получаете? Я уверен, что вы знаете, но позвольте мне напомнить, что пользователи StackOverflow не пишут для вас код, мы помогаем решать конкретные вопросы. –

+0

@ T3H40 Ну, я знаю это, я забуду добавить этот код, добавляю прямо сейчас :) – Stranger

+0

Отлично. Пожалуйста, не забудьте указать, что именно не работает :) –

ответ

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

Вот логический пример для рекурсии, вы должны только закончить внутренние коды

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

$ menuHtml должен быть вне функции, поэтому, когда вы снова запросите функцию, она не очистит ее обратно –

+0

@FahedAlkaabi Я только что добавил ее после первого сообщения, Вы видите? – Armen

+1

if (isset ($ item ['children'])) он всегда установлен, попробуйте проверить, нет ли пустого –