[英]php recursive function to built menu
我试图使用PHP构建递归菜单,但未成功
mysql表
menuid name parentid
和我的PHP代码
function generateMenubar()
{
$data = Yii::app()->db->createCommand("select * from menu");
$result = $data->queryAll();
$html = '<ul class = "navigation">';
foreach($result as $row)
{
if($row['parentid'] == "0")
{
$html .= '<li><a href="#"><span>'.$row["menuname"].'</span></a>';
$menu_id = $row['menuid'];
$html .= $this->generateHTML($result,$menu_id,$html);
}
}
return $html;
}
function generateHTML($result,$menu_id,$html)
{
foreach($result as $row_sub)
{
if($menu_id == $row_sub['parentid'])
{
$html .= '<ul><li><a href="buttons.html"><span>'.$row_sub['menuname'].'</span></a>';
$menu_id = $row_sub['menuid'];
$html .= $this->generateHTML($result,$menu_id,$html);
$html .= '</li>';
}
}
return $html.'</ui>';
}
但是此循环不会停止并生成错误的输出。 它最多可以具有n级子级。 我想使它的动态Cuz水平在将来可能有任何建议改变?
您的问题是没有迭代的结构化结果。 您可能将SubElement 2 > 3 > 4
作为第一个结果,但将2 > 3 > 1
作为第五个结果。 因此,您不能只遍历一次结果并生成html。
您想要做的事情(从切换到嵌套集 ,这是您真正想做的眨眼 ),首先要构造您的结果。
遍历您的结果并构建一个嵌套数组,以循环方式遍历以构建HTML。 要在递归数组中找到“将元素放置在何处”,您还需要始终递归检查现有数组。 如果您存储的所有内容都是id和parent id,那么在检查所有元素之前如何找出根元素是正确的? 所以我可以编写代码来这样做,但我宁愿不这样做,因为无论如何这将是一个可怕的解决方案。 为了更有效地执行此操作,如果您不仅存储您的父代信息,还存储一个级别,那将真正有帮助。 然后,您可以将元素存储在二维数组中,该数组存储每个级别的所有元素,然后递归使用该数组。 即
$navigationTempArray = array();
foreach($fakeMySQLResult as $row)
{
if(!array_key_exists($row['level'], $navigationTempArray )) {
$navigationTempArray[$row['level']] = array();
}
if(!array_key_exists($row['parentid'], $navigationTempArray[$row['level']] )) {
$navigationTempArray[$row['level']][$row['parentid']] = array();
}
$navigationTempArray[$row['level']][$row['parentid']][] = $row;
}
现在你有一个像这样的数组:
array (
0 => array(
'root' => array(
1 => array('title' => 'Start' ...)
2 => array('title' => 'Team' ...)
3 => array('title' => 'Projects' ...)
)
),
1 => array(
2 => array(
4 => array('title' => 'Development' ...)
5 => array('title' => 'Design' ...)
6 => array('title' => 'Sales' ...)
),
3 => array(
7 => array('title' => 'Mayhem' ...)
8 => array('title' => 'X' ...)
)
),
2 => array(
4 => array(
9 => array('title' => 'PHP' ...)
10 => array('title' => 'MySQL' ...)
)
)
)
现在,您可以递归遍历此数组,将每个项目的每个级别求解为无穷大 ;-)
function returnSubNavigation($id,$level,$fullNavigationArray) {
$html = '';
if(array_key_exists($level, $fullNavigationArray) && array_key_exists($id, $fullNavigationArray[$level])) {
$html .= '<ul>';
foreach($fullNavigationArray[$level][$id] as $subElement) {
$html .= '<li><a href="#"><span>'.$subElement["menuname"].'</span></a>';
$html .= returnSubNavigation($subElement['id'], $level+1, $fullNavigationArray);
$html .= '</li>';
}
$html .= '</ul>';
}
return $html;
}
echo returnSubNavigation('root', 0, $navigationTempArray);
一些不想使用嵌套集的人经常存储路径而不是父ID。 即:
| id | path |
| 1 | 1 |
| 2 | 2 |
| 3 | 1.1 |
| 4 | 1.2 |
| 5 | 2.1 |
| 6 | 3 |
迭代起来很容易(就性能而言更便宜)。 您可以轻松地对其进行排序。 尽管如此,它仍然带来许多问题和限制。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.