2011-02-03 76 views
1

我想優化一個多對多的設計,它將返回一個像結構樹。數據是這樣的:PHP mySQL結構輸出樹

頁表:ID,標題,副標題,類 網頁連接器表:ID,PAGE_ID,PARENT_ID,部分

如果部分= X,對於具有孩子每個父母其中一節= X標記應該是這樣的:

--- start parent 1 --- 
-- if first parent echo * 
<>* parent page id | parent title<> 
--- parent 1 children --- 
    <>child page id | child title<> 
    <>child page id | child title<> 
    <><>child page id | child title<> 
--- end parent 1 --- 
--- start parent 2 --- 
-- if first parent echo * 
<>parent page id | parent title<> 
--- parent 2 children --- 
    <>child page id | child title<> 
    <>child page id | child title<> 
    <>child page id | child title<> 
--- end parent 2 --- 

這種實現似乎運作良好,但我似乎無法弄清楚如何修改函數返回標記如上:

// Menu builder function, parentId 0 is the root 
function buildMenu($parent, $menuData) 
{ 
    $html = ""; 
    if (isset($menuData['parents'][$parent])) 
    { 
     $html .= " 
     <ul>\n"; 
     foreach ($menuData['parents'][$parent] as $itemId) 
     { 
      if(!isset($menuData['parents'][$itemId])) 
      { 
      $html .= "<li>\n <a href='".$menuData['items'][$itemId]['link']."'>".$menuData['items'][$itemId]['label']."</a>\n</li> \n"; 
      } 
      if(isset($menuData['parents'][$itemId])) 
      { 
      $html .= " 
      <li>\n <a href='".$menuData['items'][$itemId]['link']."'>".$menuData['items'][$itemId]['label']."</a> \n"; 
      $html .= buildMenu($itemId, $menuData); 
      $html .= "</li> \n"; 
      } 
     } 
     $html .= "</ul> \n"; 
    } 
    return $html; 
} 
echo buildMenu(0, $menuData); 

回答

0

你的數據結構看起來很奇怪。最好的我可以說,你的$ menuData結構是這樣的:

$menuData = array(
    "parents" => array(...), 
    "items" => array( 
    0 => array("link" => "...", "title" => "...", ...), 
    1 => array("link" => "...", "title" => "...", ...) 
) 
); 

在層次結構我已經建立了,他們看起來更像是這樣的:

$menuData = array(
    array("id" => 1, parent_id => 0, "link" => "...", "title" => "...", ...), 
    array("id" => 2, parent_id => 1, "link" => "...", "title" => "...", ...) 
) 
); 

也許這就是上下文你約束正在工作,但只是說:簡單的結構使得代碼更簡單。至於你的遞歸算法來生成你的樹,如果它確實生成你正在尋找的東西(至少是無序列表結構),那麼你只需要嘗試添加「<>」和「 - 」 - 「您想要在<li></li>連接之間的部分。然而,你會遇到一個問題,你的星號爲「第一」父母。如果你想要把星號來爲所有頂級菜單項,你應該buildMenu建立一個可選的參數,像這樣:

function buildMenu($parent, $menuData, $level = 0); 

然後修改您的遞歸調用,像這樣:

$html .= buildMenu($itemId, $menuData, ++$level); 

,並添加狀態檢測時,$水平== 0

$html .= "<li>\n " . ($level == 0 ? "*" : "") . "<a href='".$menuData['items'][$itemId]['link']."'>".$menuData['items'][$itemId]['label']."</a>\n</li> \n"; 

如果你只是想在第一頂級父一個星號,你最好還是先建立福範圍之外的全局變量並設置一次性標誌條件,以便在第一次調用代碼時僅輸出一個星號,而不再一次。

希望這會有所幫助。