2014-01-11 61 views
3

我有一個數組titlechildren索引。如何從數組樹中創建ul-li菜單?

title總是非空。 children是一個數組,爲空或非空。

任何children都有titlechildren等等。

$myArray = [ 
    0 => [ 
     'title' => 'N1', 
     'children' => 
      [ 
       0 => 
        [ 
         'title' => 'N11', 
         'children' => 
          [ 
           0 => 
            [ 
             'title' => 'N111', 
             'children' => [], 
            ], 
          ], 
        ], 
      ], 
    ], 
    1 => 
     [ 
      'title' => 'N2', 
      'children' => 
       [ 
        0 => 
         [ 
          'title' => 'N21', 
          'children' => 
           [], 
         ], 
       ], 
     ], 
]; 

現在,我想用這個數組創建一個下拉菜單。

我在創建這個數組的無序列表(ulli)時遇到了問題。

我希望我的結果是這樣的:

<ul> 
    <li>N1 
     <ul> 
      <li>N11 
       <ul> 
        <li>N111</li> 
       </ul> 
      </li> 
     </ul> 
    </li> 
    <li>N2 
     <ul> 
      <li>N21</li> 
     </ul> 
    </li> 
</ul> 
+1

好吧,這個問題很好說明。你有這樣的代碼嗎?要開始,你需要一個帶有'foreach'循環的函數,然後完成它,它將需要遞歸。 – halfer

+2

最初代碼中的問題是printMenu函數中的$ array和$ item變量引用了最頂層運行的值。請按照以下步驟操作(在您的遞歸函數之外循環) –

+0

啊,您確實有初始嘗試 - 您爲什麼要刪除它? – halfer

回答

9

我敢肯定,這將工作:

function menu($arr) { 
     echo "<ul>"; 
     foreach ($arr as $val) { 

      if (!empty($val['children'])) { 
       echo "<li>" . $val['title']; 
       menu($val['children']); 
       echo "</li>"; 
      } else { 
       echo "<li>" . $val['title'] . "</li>"; 
      } 
     } 
     echo "</ul>"; 
    } 
+0

這不會在OP的預期結果中創建兩個根目錄「ul」而不是一個? – k0pernikus

2

假設這是你的陣列

$menu = array(
    array(
     'title'=>'N1', 
     'children'=>array(
       'title'=>'N11', 
       'children'=>array(
         'title'=>'N111', 
         'children'=>array(), 
       ), 
     ), 
    ), 
    array(
     'title'=>'N2', 
     'children'=>array(
       'title'=>'N21', 
       'children'=>array(), 
       ) 
    ), 
); 

你可以使用遞歸來構建這個HTML結構。

function createMenu($arr){ 
     $str = ''; 
     if(is_array($arr)){ 
      $str .= "<li>".$arr['title']; 
     if(!empty($arr['children'])){ 
     $str .="<ul>"; 
     $str .= createMenu($arr['children'],$str);     
     $str .="</ul>"; 
     } 
     $str .= "</li>";    
     } 
    return $str; 
    } 

現在所說的遞歸函數來創建HTML

$myMenu =''; 
foreach($menu as $arr){ 
    $myMenu .= createMenu($arr); 
} 
echo "<ul>".$myMenu."</ul>"; 
exit(); 
+2

廣義上這是一個很好的答案(雖然我認爲函數應該返回值而不是使用傳遞參考參數)。但是,並非鼓勵OP自己去思考問題,而是將答案交給了一個盤子。這解決了他們眼前的問題,但我不確定它有什麼東西。 – halfer

+3

@hafler我已更新我的代碼。我對此造成的任何不便表示歉意.. :) –

+0

感謝您的回覆 –

0

我必須實現類似的東西,但我想要的HTML代在twig模板中。這可能是這樣的:

{% macro printMenuElements(nestedListElements, level = 0, parent = 'root') %} 
    <ul> 
     {% for nestedElement in nestedListElements %} 
      {% set children = nestedElement.children %} 
      {% set title = nestedElement.title %} 


      {% if children is not empty and children is iterable %} 
       <li data-parent="{{ parent }}"> 
        {{ title }} 
        {{ _self.printMenuElements(children, level +1, title) }} 
       </li> 
      {% else %} 
       <li data-parent="{{ parent }}"> 
        {{ title }} 
       </li> 
      {% endif %} 
     {% endfor %} 
    </ul> 
{% endmacro %} 

{% block body %} 
    <h1>Menu</h1> 
    {% import _self as helper %} 
    {{ helper.printMenuElements(yourArray) }} 
{% endblock %} 

生成的HTML輸出:

<ul> 
 
    <li data-parent="root"> 
 
     N1 
 
     <ul> 
 
      <li data-parent="N1"> 
 
       N11 
 
       <ul> 
 
        <li data-parent="N11"> 
 
         N111 
 
        </li> 
 
       </ul> 
 
      </li> 
 
     </ul> 
 
    </li> 
 
    <li data-parent="root"> 
 
     N2 
 
     <ul> 
 
      <li data-parent="N2"> 
 
       N21 
 
      </li> 
 
     </ul> 
 
    </li> 
 
</ul>