从数组构建递归嵌套菜单 [英] Build recursive nested menu from array
问题描述
我正在尝试构建一个递归菜单,完成后看起来像这样,带有无限数量的嵌套项目:
I'm trying to build a recursive menu which would look something like this when finished, with an infinite amount of nested items:
Homepage
Services
Members
Brokers
Insurers
Products
我的数据通过表中的简单parent_id
列链接在一起.
My data is being linked together by a simple parent_id
column in my table.
我目前设法抓取了表格中的所有页面,并根据它们的parent_id
将它们添加到数组中(见下文).
I have currently managed to grab all the pages in the table and add them into an array based on their parent_id
(see below).
Array
(
[0] => 0-0-1 0-1-2 0-2-12 0-3-27 0-4-28 0-5-29 0-6-30 0-7-31 0-8-33
[2] => 2-0-3 2-0-6 2-0-7 2-0-8
[3] => 3-0-4 3-0-5
[8] => 8-0-9 8-0-10
[12] => 12-0-13 12-0-20
[13] => 13-0-14 13-1-15 13-2-17 13-3-16 13-4-19 13-5-18 13-9-34
[20] => 20-0-21 20-1-22 20-2-24 20-3-23 20-4-26 20-5-25 20-6-11
)
它的格式为[parent_id
] => parent_id
-sort_order
-id
parent_id
-sort_order
-id
,依此类推.
This is formatted as [parent_id
] => parent_id
-sort_order
-id
parent_id
-sort_order
-id
and so on.
到目前为止,我的代码如下:
My code so far is as follows:
$sqlGetDropdownPages = "SELECT * FROM `cms_staticPages` ORDER BY `sortOrder` ASC";
$qryGetDropdownPages = mysql_query($sqlGetDropdownPages) or die(mysql_error());
$resGetDropdownPages = mysql_fetch_assoc($qryGetDropdownPages);
$totGetDropdownPages = mysql_num_rows($qryGetDropdownPages);
do {
$pageArray[$resGetDropdownPages['parent_id']] .= $resGetDropdownPages['parent_id'].'-'.$resGetDropdownPages['sortOrder'].'-'.$resGetDropdownPages['id'].' ';
} while($resGetDropdownPages = mysql_fetch_assoc($qryGetDropdownPages));
ksort($pageArray);
foreach($pageArray as $i => $value) {
$explodePages = explode(' ',$value);
foreach(array_filter($explodePages) as $i2 => $page) {
$pageInfoExplode = explode('-',$page);
$getPageInfo = mysql_fetch_assoc(mysql_query("SELECT * FROM `cms_staticPages` WHERE `id` = '".$pageInfoExplode[2]."'"));
echo $getPageInfo['identifier'].'<br />';
}
}
这时碰上一堵砖墙,不知道下一步该怎么做.
Ran into a brick wall at this point and can't figure out what to do next.
我尽力解释了这一点,所以是否需要澄清就问一下.
I tried to explain this as well as I possibly can so if any clarification is needed just ask.
如何实现?
推荐答案
我将首先按ID为所有菜单项(页面)建立索引.在第二个循环中,将菜单项与其父母相关联,并跟踪顶级项.
I would index all the menu items (pages) by id first. In the second loop associate menu items with their parents and keep track of top level items.
我会做的一种方法(Render方法只是一个例子):
One of the ways I would do it (Render method is just an example):
$sqlGetDropdownPages = "SELECT * FROM `cms_staticPages` ORDER BY `sortOrder` ASC";
$qryGetDropdownPages = mysql_query($sqlGetDropdownPages) or die(mysql_error());
//indexing pages by id
while ($pageRow = mysql_fetch_assoc($qryGetDropdownPages)) {
$menuItems[$pageRow['id']] = new MenuItem($pageRow);
}
//associating pages with parents
foreach ($menuItems as $menuItem) {
if ($menuItem->hasParent()) {
$menuItem->addToParent($menuItems);
} else {
$topLevel[] = $menuItem;
}
}
//$topLevel is an array of menuItems without parents
$render = '<ul>';
foreach ($topLevel as $menuItem) {
$render .= $menuItem->render(true);
}
$render .= '</ul>';
MenuItem类看起来像这样
MenuItem class would look something like this
class MenuItem {
/**
* @var array
*/
private $data;
/**
* @var MenuItem[]
*/
private $children = array();
/**
* @var MenuItem
*/
private $parent;
/**
* @param array $data
*/
public function __construct($data) {
$this->data = $data;
}
/**
* Finds the parent in the collection and adds itself to it
* @param MenuItem[] $menuItems
*/
public function addToParent($menuItems) {
if (isset($menuItems[$this->data['parent_id']])) {
$this->parent = $menuItems[$this->data['parent_id']];
$this->parent->addChild($this);
}
}
/**
* @return bool
*/
public function hasParent() {
return empty($this->data['parent_id']);
}
/**
* @param MenuItem $child
*/
public function addChild(MenuItem $child) {
$this->children[] = $child;
}
/**
* Renders the menu with ul li
* @param bool $withChildren
* @return string
*/
public function render($withChildren = false) {
$render = '<li>' . $this->data['identifier'] . '</li>';
if ($withChildren) {
$render .= '<ul>';
foreach ($this->children as $child) {
$render .= $child->render(true);
}
$render .= '</ul>';
}
return $render;
}
}
这篇关于从数组构建递归嵌套菜单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!