2011-02-03 77 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"; 

如果你只是想在第一顶级父一个星号,你最好还是先建立福范围之外的全局变量并设置一次性标志条件,以便在第一次调用代码时仅输出一个星号,而不再一次。

希望这会有所帮助。