[英]PHP Recursive menu function
I have a very similar situation to this post 我的情况与此相似
PHP: nested menu with a recursive function, expand only some nodes (not all the tree) PHP:具有递归功能的嵌套菜单,仅扩展某些节点(并非所有树)
and I need some help... 我需要一些帮助...
Here is the (partial) contents of my $menuJSONArray variable (used when calling the function): 这是我的$ menuJSONArray变量(调用函数时使用)的(部分)内容:
Array
(
[0] => Array
(
[Menu_IDX] => 1
[Order] => 1
[Name] => History
[Parent] =>
[Path] => History
[Link] =>
)
[1] => Array
(
[Menu_IDX] => 2
[Order] => 25
[Name] => Review
[Parent] =>
[Path] => Review
[Link] => Review
)
[2] => Array
(
[Menu_IDX] => 3
[Order] => 35
[Name] => Past Medical History
[Parent] =>
[Path] => Past Medical History
[Link] => Past Medical History
)
[3] => Array
(
[Menu_IDX] => 4
[Order] => 45
[Name] => Item 1
[Parent] => 0
[Path] => Item 1
[Link] => Item 1
)
[4] => Array
(
[Menu_IDX] => 5
[Order] => 55
[Name] => Item 2
[Parent] => 0
[Path] => Item 2
[Link] => Item 2
)
[5] => Array
(
[Menu_IDX] => 6
[Order] => 65
[Name] => Item 3
[Parent] => 0
[Path] => Item 3
[Link] => Item 3
)
)
and so on... 等等...
I am using the function below but I keep getting stuck in the loop at the first item. 我正在使用下面的函数,但是在第一项中我一直陷于循环中。 Really need some help wrapping my brain around this function.
确实需要一些帮助使我的脑筋围绕此功能。 Thank you all ahead of time, this community rocks!!
提前谢谢大家,这个社区动摇了!!
///RECURSIVE MENU
function recursive($parent, $array) {
$has_children = false; //set value of has children to false by default
foreach($array as $key => $value) { //loop through the array as key-value pairs
if ($value['Parent'] == $parent) { //if the value of Parent field is equal to parent variable
if ($has_children === false && $parent) { //if children is false but parent is not null, this is a sub item
$has_children = true; //children is true
echo '<ul>' ."\n"; //create parent menu ul
} //otherwise just create the item
echo '<li>' . "\n"; //create li for parent menu item
echo '<a href="'.$value['Path'].'">' . $value['Name'] . '</a>' . " \n"; //create link for menu item
recursive($key, $array); //create sub menu
echo "</li>\n"; //end parent menu item
}
}
if ($has_children === true && $parent) echo "</ul>\n"; //end parent menu
}
?>
<?php echo recursive(0, $menuJSONArray); ?></ul>
What I get in return is: 我得到的回报是:
<ul>
<li>
<a href="History">History</a>
<li>
<a href="History">History</a>
<li>
<a href="History">History</a>
<li>
<a href="History">History</a>
<li>
<a href="History">History</a>
<li>
<a href="History">History</a>
Can't seem to get out of this loop. 似乎无法摆脱这种循环。 Thanks!!
谢谢!!
PS I am not concerned with the collapsing of the tree etc. from the referenced post as I will be handling that with jquery and css. PS我不关心树的崩溃等从引用的职位,因为我将使用jQuery和CSS处理。 I just cannot get the proper output of the menu syntax.
我只是无法获得菜单语法的正确输出。
As I agree with @Tim Withers I start to solve problem from preparing current array: 正如我同意@Tim Withers一样,我从准备当前数组开始解决问题:
function prepareMenu($array)
{
$return = array();
//1
krsort($array);
foreach ($array as $k => &$item)
{
if (is_numeric($item['Parent']))
{
$parent = $item['Parent'];
if (empty($array[$parent]['Childs']))
{
$array[$parent]['Childs'] = array();
}
//2
array_unshift($array[$parent]['Childs'],$item);
unset($array[$k]);
}
}
//3
ksort($array);
return $array;
}
Some explanation. 一些解释。
Then function to build menu: 然后建立菜单功能:
function buildMenu($array)
{
echo '<ul>';
foreach ($array as $item)
{
echo '<li>';
echo $item['Name'];
if (!empty($item['Childs']))
{
buildMenu($item['Childs']);
}
echo '</li>';
}
echo '</ul>';
}
With this and proper array order, no matter how deep rabbit hole is - you have your tree. 通过这种适当的排列顺序,无论兔子洞有多深,您都可以拥有自己的树。
Usage: 用法:
$menu = prepareMenu($menu);
buildMenu($menu);
Of course... There must be better way... :-P 当然...一定有更好的方法... :-P
EDIT: 编辑:
For array (a little midification [next child]): 对于数组(有点中间[下一个孩子]):
$menu = array(
array(
'Menu_IDX' => '1',
'Order' => '1',
'Name' => 'History',
'Parent' => '',
'Path' => 'History',
'Link' => '',
),
array
(
'Menu_IDX' => '2',
'Order' => '25',
'Name' => 'Review',
'Parent' => '',
'Path' => 'Review',
'Link' => 'Review',
),
array
(
'Menu_IDX' => '3',
'Order' => '35',
'Name' => 'Past Medical History',
'Parent' => '',
'Path' => 'Past Medical History',
'Link' => 'Past Medical History',
),
array
(
'Menu_IDX' => '4',
'Order' => '45',
'Name' => 'Item 1',
'Parent' => '0',
'Path' => 'Item 1',
'Link' => 'Item 1',
),
array
(
'Menu_IDX' => '5',
'Order' => '55',
'Name' => 'Item 2',
'Parent' => '0',
'Path' => 'Item 2',
'Link' => 'Item 2',
),
array
(
'Menu_IDX' => '6',
'Order' => '65',
'Name' => 'Item 3',
'Parent' => '0',
'Path' => 'Item 3',
'Link' => 'Item 3',
),
array
(
'Menu_IDX' => '7',
'Order' => '65',
'Name' => 'Item 31',
'Parent' => '5',
'Path' => 'Item 31',
'Link' => 'Item 31',
)
);
Output will be: 输出将是:
Plenty of detail in your question, that's great. 您的问题中有很多细节,这很棒。
Looking at the code, the first issue I see is with the line: 查看代码,我看到的第一个问题是该行:
if ($value['Parent'] == $parent) {
The first time you enter the foreach loop, $value['Parent']
is NULL
, and $parent
is 0
. 第一次进入foreach循环时,
$value['Parent']
为NULL
,而$parent
为0
。
Because you are doing a ==
comparison, this evaluates to TRUE
. 因为您正在进行
==
比较,所以计算结果为TRUE
。 Try instead: 请尝试:
if ($value['Parent'] === $parent) {
Note the ===
. 注意
===
。 This also checks the data type and requires it to match as well. 这还将检查数据类型,并要求它也匹配。
The second issue will then be with the line: 第二个问题将是:
if ($has_children === false && $parent) { //if children is false but parent is not null, this is a sub item
The comment makes it clear that you want to check that $parent
is not null, but you aren't doing that, you are casting the integer value of $parent
to a Boolean, so 0
will be treated as FALSE
, and anything else as TRUE
. 该注释清楚表明,您要检查
$parent
不为null,但您没有这样做,您正在将$parent
的整数值转换为布尔值,因此0
将被视为FALSE
,而其他将被视为TRUE
。
Try instead: 请尝试:
if ($has_children === false && !is_null($parent)) { //if children is false but parent is not null, this is a sub item.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.