在php中显示多级数据库驱动菜单
我想显示一个数据库驱动的多级菜单,下面是我迄今为止尝试过的,但我没有得到预期的结果。有人能帮我修一下吗。我得到的输出只是父id为0的主菜单,而不是子菜单项在php中显示多级数据库驱动菜单,php,mysql,Php,Mysql,我想显示一个数据库驱动的多级菜单,下面是我迄今为止尝试过的,但我没有得到预期的结果。有人能帮我修一下吗。我得到的输出只是父id为0的主菜单,而不是子菜单项 <?php include('system/connection.php'); ?> <?php //select all rows from the main_menu table $q = "SELECT * FROM catelogue WHERE cat_visibility = '1'"; $r = mysqli
<?php
include('system/connection.php');
?>
<?php
//select all rows from the main_menu table
$q = "SELECT * FROM catelogue WHERE cat_visibility = '1'";
$r = mysqli_query($dbc, $q);
echo "<ul class='dropdown'>";
while ($rows = mysqli_fetch_assoc($r)) {
if ($rows['cat_parentid'] == 0) {
echo "<li><a href='#'>" . $rows['cat_name'] . "</a>";
echo "<ul>";
foreach ($rows as $item) {
if ($item['cat_parentid'] == $rows['cat_id']) {
echo "<li><a href='#'>" . $item['cat_name'] . "</a>";
echo "</li>";
}
}
echo "</ul>";
echo "</li>";
}
}
echo "</ul>";
?>
我想要的期望输出:
<ul class="dropdown">
<li><a href='#'>Home</a></li>
<li><a href='#'>About</a>
<ul>
<li><a href='#'>History</a></li>
<li><a href='#'>Services</a></li>
</ul>
</li>
<li><a href='#'>Contact</a></li>
</ul>
-
您所谓的$rows
实际上是一行。然后,在foreach($rows as$item)
循环中,它遍历此行的列。因此,没有$item['cat\u parentid']
。使用var\u dump()
尝试查看$rows
和$item
的输出
我想到的一个可能解决方案的初步想法是,首先迭代结果行,并将子项保存在父项中(注意:此处必须添加一些数组初始化):
然后遍历$menuItems
数组生成输出,这将非常有用
此外,对sql结果进行排序也会很有好处,可以确保最上面的菜单项排在第一位:
"SELECT * FROM catelogue WHERE cat_visibility = '1' ORDER BY cat_parentid ASC";
您所称的
$rows
实际上是一行。然后,在foreach($rows as$item)
循环中,它遍历此行的列。因此,没有$item['cat\u parentid']
。使用var\u dump()
尝试查看$rows
和$item
的输出
我想到的一个可能解决方案的初步想法是,首先迭代结果行,并将子项保存在父项中(注意:此处必须添加一些数组初始化):
然后遍历$menuItems
数组生成输出,这将非常有用
此外,对sql结果进行排序也会很有好处,可以确保最上面的菜单项排在第一位:
"SELECT * FROM catelogue WHERE cat_visibility = '1' ORDER BY cat_parentid ASC";
您所称的
$rows
实际上是一行。然后,在foreach($rows as$item)
循环中,它遍历此行的列。因此,没有$item['cat\u parentid']
。使用var\u dump()
尝试查看$rows
和$item
的输出
我想到的一个可能解决方案的初步想法是,首先迭代结果行,并将子项保存在父项中(注意:此处必须添加一些数组初始化):
然后遍历$menuItems
数组生成输出,这将非常有用
此外,对sql结果进行排序也会很有好处,可以确保最上面的菜单项排在第一位:
"SELECT * FROM catelogue WHERE cat_visibility = '1' ORDER BY cat_parentid ASC";
您所称的
$rows
实际上是一行。然后,在foreach($rows as$item)
循环中,它遍历此行的列。因此,没有$item['cat\u parentid']
。使用var\u dump()
尝试查看$rows
和$item
的输出
我想到的一个可能解决方案的初步想法是,首先迭代结果行,并将子项保存在父项中(注意:此处必须添加一些数组初始化):
然后遍历$menuItems
数组生成输出,这将非常有用
此外,对sql结果进行排序也会很有好处,可以确保最上面的菜单项排在第一位:
"SELECT * FROM catelogue WHERE cat_visibility = '1' ORDER BY cat_parentid ASC";
这是一个递归解决方案 代码已完全注释
processMenuEntry
例程中有两个有用的检查,可以方便地执行,以便您可以决定是否要执行不同的操作
- 检查“当前”条目是否为“根”节点
$isRoot=$currentEntry['cat_id']==0;//进行“首次”处理
- 检查当前“条目”是否有“子菜单”
if(!empty($subMenu)){…
$DB_HOST = "localhost";
$DB_USER = "test";
$DB_PASSWORD = "test";
$DB_TO_USE = "testmysql";
$dbc = new mysqli($DB_HOST, $DB_USER, $DB_PASSWORD, $DB_TO_USE);
子菜单查询:
/** -----------------------------------------------------------------
* Select all the menu entries for a given entry Id
*
* Note: it is safe to do 'parameter substitution' rather than using
* 'prepared queries' with placeholders as this 'entry Id' never
* comes from an external source.
*
* @param mysqli $dbc
* @param integer $currentEntryId
* @return array of menu entries
*/
function selectSubMenu($currentEntryId, $dbc)
{
$sql = "SELECT cat_id, cat_name, cat_parent_id
FROM catalogue
WHERE cat_parent_id = {$currentEntryId}
ORDER BY cat_id";
$resultSet = mysqli_query($dbc, $sql);
return $resultSet->fetch_all(MYSQLI_ASSOC);
}
处理当前菜单项:
/** --------------------------------------------------------------------------
* Process the current menu enty - it will return a complete menu as HTML
*
* These needs to know whether the current entry has a submenu and
* will therefore need to generate an 'unordered list' for the current entry.
*
* Alas, it also has to not display the 'list item text' for the 'root' entry
* but process the 'submenu'.
* This complicates the <li> current entry text generation slightly.
*
* @param array $currentEntry - one row
* @param array $subMenu - many rows - may be empty
* @param mysqli $dbc - database connection
* @return string - the HTML for the menu
*/
function processMenuEntry($currentEntry, array $subMenu, $dbc) {
$outMenu = '';
$isRoot = $currentEntry['cat_id'] == 0; // do 'First time' processing
// display the current entry text as a 'list item'
$outMenu .= !$isRoot ? "<li><a href='#'>" . $currentEntry['cat_name'] . "</a>" : '';
// does it have a submenu...
if (!empty($subMenu)) { // we need to add a complete submenu of <ul> ... </ul>
// Start of the submenu as an unordered list -- decide what is required
if ($isRoot) {
$outMenu .= '<ul class="dropdown">';
}
else {
$outMenu .= '<ul>';
}
// Display each entry of the submenu as a 'list item'
foreach ($subMenu as $submenuEntry) {
$outMenu .= processMenuEntry($submenuEntry,
selectSubMenu($submenuEntry['cat_id'], $dbc),
$dbc);
}
// close the current submenu - terminate the unordered list
$outMenu .= '</ul>';
}
// terminate the current list item
$outMenu .= !$isRoot ? '</li>' : '';
return $outMenu;
};
/**--------------------------------------------------------------------------
*处理当前菜单条目-它将以HTML形式返回完整的菜单
*
*这些需要知道当前条目是否有子菜单和
*因此,需要为当前条目生成“无序列表”。
*
*唉,它还必须不显示“根”条目的“列表项文本”
*但要处理“子菜单”。
*这使当前条目文本生成稍微复杂化。
*
*@param数组$currentEntry-一行
*@param array$子菜单-多行-可能为空
*@param mysqli$dbc-数据库连接
*@return string-菜单的HTML
*/
函数ProcessMentry($currentEntry,array$子菜单,$dbc){
$outMenu='';
$isRoot=$currentEntry['cat_id']==0;//执行“第一次”处理
//将当前条目文本显示为“列表项”
$outMenu.=!$isRoot?”“:”;
//它是否有子菜单。。。
如果(!empty($subMenu)){//我们需要添加一个完整的子菜单。
//以无序列表的形式开始子菜单--确定所需内容
如果($isRoot){
$outMenu.=';
}
否则{
$outMenu.='';
}
//将子菜单的每个条目显示为“列表项”
foreach($子菜单作为$子菜单项){
$outMenu.=processMenuEntry($submenuEntry,
选择子菜单($submenuEntry['cat_id',$dbc),
$dbc);
}
//关闭当前子菜单-终止无序列表
$outMenu.='
';
}
//终止当前列表项
$outMenu.=!$isRoot?“
”:”;
返回$outMenu;
};
处理所有菜单项:
/* -------------------------------------------------------------------
* Process all the menu entries
*
* We need a complete menu 'tree' that includes a 'root' which is not provided
* in the database. I think it should be. Whatever, i need one.
*
* Initializing a 'tree walk' i always find 'interesting' ;-/
*/
$root = array('cat_id' => 0, 'cat_name' => '', 'cat_parent_id' => 0);
// build the output menu
$outMenu = processMenuEntry($root,
selectSubMenu($root['cat_id'], $dbc),
$dbc);
// wrap it in a <div>
$htmlMenu = '<div style="border: 1px solid red">'
. $outMenu
.'</div>';
?>
/*-------------------------------------------------------------------
*过程
<!DOCTYPE html>
<html>
<head>
<title>Test Recursive Menu Builder
</title>
</head>
<body>
<div style="border: 1px solid red">
<ul class="dropdown">
<li>
<a href='#'>Home</a>
</li>
<li>
<a href='#'>About</a>
<ul>
<li>
<a href='#'>History</a>
</li>
<li>
<a href='#'>Services</a>
</li>
</ul>
</li>
<li>
<a href='#'>Contact</a>
</li>
</ul>
</div>
</body>
</html>