PHP mySQL结构输出树

时间:2011-02-03 22:12:20

标签: php mysql tree join

我正在尝试优化多对多设计,这将返回树状结构。数据如下所示:

页面表:id,title,subtitle,class pages连接器表:id,page_id,parent_id,section

如果section = x,对于每个有子节点的父节点,section = x markup应该是这样的:

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

1 个答案:

答案 0 :(得分: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" => "...", ... )
  )
);

也许这是对你正在使用的上下文的约束,但只是说:更简单的结构使得代码更简单。

至于生成树的递归算法,如果它确实生成了你想要的东西(至少是无序列表结构),你只需要尝试添加你的“&lt;&gt;”和“ - ”在<li></li>串联之间所需的部分。但是,对于“第一个”父级,您的星号会有问题。如果要将星号添加到所有顶级菜单项,则应在buildMenu上建立可选参数,如下所示:

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

然后修改你的递归调用:

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

添加条件以检测$ level == 0

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

如果您只想在第一个顶级父级上使用星号,那么最好只在函数范围之外建立一个全局变量,并将一次性标志条件设置为仅在第一次输出星号时代码被调用,而且永远不会再被调用。

希望这有帮助。