2016-06-21 43 views
1

我需要從數據庫顯示菜單的幫助。 這裏是從數據庫表數組結果:遞歸函數,只顯示父,子女和兄弟姐妹的動態菜單

global $menuItems; 
$menuItems = array(
[ 
    'id' => 1, 
    'name' => 
    'Main Menu 1', 
    'main' => 1, 
    'parent_id' => null 
], 
['id' => 9,'name' => 'Main Menu 2','main' => 1,'parent_id' => null], 
['id' => 10,'name' => 'Main Menu 3','main' => 1,'parent_id' => null], 
['id' => 11,'name' => 'Sub Menu 1.1','main' => null,'parent_id' => 1], 
['id' => 12,'name' => 'Sub Menu 1.2','main' => null,'parent_id' => 1], 
['id' => 13,'name' => 'Sub Menu 1.3','main' => null,'parent_id' => 1], 
['id' => 14,'name' => 'Sub Menu 1.2.1','main' => null,'parent_id' => 12], 
['id' => 15,'name' => 'Sub Menu 1.2.1','main' => null,'parent_id' => 12], 
['id' => 16,'name' => 'Sub Menu 3.1','main' => null,'parent_id' => 10,], 
['id' => 17,'name' => 'Sub Menu 3.2','main' => null,'parent_id' => 10], 
['id' => 18,'name' => 'Sub Menu 3.2.1','main' => null,'parent_id' => 17], 
['id' => 19,'name' => 'Sub Menu 3.2.2','main' => null,'parent_id' => 17]); 

我已成功研製菜單樹從下面的代碼:

foreach ($menuItems as $menu) { 
    $parentsIds[$menu['id']] = $menu['parent_id']; 
} 
function parseAndPrintTree($root, $tree) { 
    global $menuItems; 
    $return = array(); 
    if(!is_null($tree) && count($tree) > 0) { 
     echo '<ul>'; 
     foreach($tree as $child => $parent) { 
      if($parent == $root) {      
      unset($tree[$child]); 
      foreach ($menuItems as $row) { 
       if($row['id'] == $child) 
      echo "<li><a href='?menu=".$row['id']."'>".$row['name']. </a>"; 
      }  
      parseAndPrintTree($child, $tree); 
      echo '</li>'; 
     } 
    } 
    echo '</ul>'; 
    } 
} 

parseAndPrintTree(0,$parentsIds); 

它打印出所需的輸出。

我需要的是每一個菜單點擊時,

  1. 所有的孩子(如果有,直到點擊不應印刷更多的孩子)
  2. 所有它的兄弟姐妹
  3. 並且其父母回到根parent_id=0

will「on ly「與其parent_id爲0的其他主菜單(不是他們的孩子)一起打印在屏幕上。

我需要下列輸出來生成(步驟)。

在第一步驟1:

當在 「主菜單1」 被點擊:

當 「子菜單1.2」 點:

當 「主菜單3」

當點擊了 「子菜單3.2」

我傳遞?menu={$row['id']}爲獲得家長和CHILDES,但找不出點擊瞭如何處理所有的兄弟姐妹,父母和孩子。

我試過將循環中的$_GET['menu'] id與一個單獨的函數進行比較,該函數只打印一個級別的打印結果,但是當樹深度第二級時,它的第一個父級(不會打印)。

我只需要在PHP中不使用jQuery,Css(類)。因爲我不想打印屏幕上的其他菜單不只是隱藏它們。

+0

不知道,但無論如何:完整路徑添加到您的陣列,以母公司和到節點本身(例如通過首先在其上運行遞歸)。如果節點以該值開始並以所選節點的值開始,則只顯示一個節點(並且只能遞減)。如果您選擇例如3.2.1,你的節點值是「3.2.1」,父值是「3.2」。現在只顯示您選擇的節點值將以您測試節點的父值開始的節點(例如,3.1的父路徑是「3」,「3.2.1」以「3」開頭,因此它很好。「3.1 .2「的父=」3.1「不在」3.2.1「) – Solarflare

+0

我已經寫了菜單的例子,實際上這將用於類別。它的子類別等等,所以如果我添加完整路徑給父母,那麼當這個類別被刪除時,我也必須更新它的路徑。因此,如果可能的話,我會用遞歸來找到這個問題,這將解決問題並節省複雜性。 –

+0

是的,這就是爲什麼我說你可以先遞歸地做到這一點。運行一次以更新路徑(每次或僅在更改後),然後執行另一次遞歸以顯示它。不幸的是,如果你想使用遞歸,你將不能單獨使用一個遞歸。您當然可以編寫一個函數來測試節點的父節點是否將您的dest節點作爲子節點,但是這可以作爲遞歸使用,並且速度較慢(運行頻率更高)。如果你真的使用數據庫,你可能會使用嵌套集(它們基本上爲你提供路徑),但兄弟姐妹可能仍然有問題。 – Solarflare

回答

0

既然你說過你想讓代碼在PHP而不是JS Jquery中。我試過這個。它迭代你的數組三次,在它內部構建一個嵌套樹,即你所需要的。

定義你的陣列$的菜單項這裏爲什麼在您添加標記「MySQL的」用代碼去下面

<ul> 
<?php 
    foreach($menuItems as $menu) 
    { 
     if($menu['main'] == 1) 
     { 
     ?> 
     <li> 
      <a href='<?= '?activeMenu='.$menu['id'] ?>'><?php echo $menu['name']; ?></a> 
      <?php 
      if(isset($_GET['activeMenu']) && $_GET['activeMenu'] == $menu['id']) 
      { 
      ?> 
       <ul> 
       <?php 
       foreach($menuItems as $submenu_level1) 
       { 
        if($submenu_level1['parent_id'] == $_GET['activeMenu']) 
        { 
        ?> 
         <li> 
          <a href='<?= '?activeMenu='.$_GET['activeMenu'].'&activeSubMenu='.$submenu_level1['id'] ?>'><?php echo $submenu_level1['name']; ?> 
         <?php 
          if(isset($_GET['activeMenu']) && isset($_GET['activeSubMenu']) && $_GET['activeMenu'] == $menu['id'] && $_GET['activeSubMenu'] == $submenu_level1['id']) 
          { 
           foreach($menuItems as $submenu_level2) 
           {  
           ?> 
            <ul> 
            <?php 
             if($submenu_level2['parent_id'] == $_GET['activeSubMenu']) 
             { 
            ?> 
              <li><a href='<?= $_SERVER['PHP_SELF'] ?>'><?php echo $submenu_level2['name']; ?></li> 
            <?php 
             } 
            ?> 
            </ul> 
           <?php 
           } 
          } 
         ?> 
         </li> 
        <?php 
        } 
       } 
       ?> 
       </ul> 
      <?php 
      } 
      ?> 
     </li> 
     <?php 
     } 
    } 
?> 
</ul> 
+0

它正確地工作兩個級別,當我點擊子菜單1.2它正確顯示子菜單1.2.1和子菜單1.2.2(換句話說子菜單第二級別的子)。但是當我添加另一個級別時,子菜單1.2.2的子菜單作爲子菜單1.2.2.A。在** $ menuItems ** '['id'=> 20,'name'=>'Sub Menu 1.2.2.A','main'=> null,'parent_id'=> 15]' (an其他孩子的水平)。 它不會迭代到底部,顯然循環是第三級下降。我需要一些遞歸類型,如果可能的話,它不會在底層綁定。 –

+0

任何人到達這裏;儘管這對我來說並不明確,但它幫助我解決了問題,實際上我做的是,我將孩子限制在5級以下,並實施了Vijay Wilson的解決方案。 –