php和mysql目录样式数据库中的子菜单
我一直试图通过php和mysql在每个主菜单上创建一个包含子菜单的菜单,然后在每个子菜单上创建子菜单。我觉得我已经快到了,但我对php和mysql还不熟悉,所以我来这里寻求你们的帮助。 我已经搜索了几个小时的答案,我找到了下拉菜单的例子,但没有一个像这样 不确定如何在此处添加sql数据库,但如果请求,将尝试添加 到目前为止,我的php代码如下php和mysql目录样式数据库中的子菜单,php,mysql,list,drop-down-menu,nested-loops,Php,Mysql,List,Drop Down Menu,Nested Loops,我一直试图通过php和mysql在每个主菜单上创建一个包含子菜单的菜单,然后在每个子菜单上创建子菜单。我觉得我已经快到了,但我对php和mysql还不熟悉,所以我来这里寻求你们的帮助。 我已经搜索了几个小时的答案,我找到了下拉菜单的例子,但没有一个像这样 不确定如何在此处添加sql数据库,但如果请求,将尝试添加 到目前为止,我的php代码如下 $result = mysqli_query($link, 'SELECT * FROM library WHERE parent_id =' . $pa
$result = mysqli_query($link, 'SELECT * FROM library WHERE parent_id =' . $parent_id = 0);
$subResult = mysqli_query($link, 'SELECT * FROM library WHERE parent_id >'. $parent_id);
if(mysqli_num_rows($result) > 0) {
echo '<ul class="nav list">';
while($row = mysqli_fetch_array($result))
{
echo '<li class="nav-item">'. '<a href="#">'.$row['mainfolder'] .'</a>'.
'<ul class="dropdown-content nav">';
while($sub = mysqli_fetch_array($subResult))
{
if($row['id']===$sub['parent_id'])
{
echo $sub['parent_id'];
$submenuItems = mysqli_query($link, 'SELECT mainfolder FROM library WHERE parent_id ='. $sub['parent_id']);
$items = mysqli_fetch_array($submenuItems);
foreach ($items as $eachItem){
echo' <li class="submenu">'.'<a class="sub" href="#">'.htmlspecialchars($eachItem, ENT_QUOTES, 'UTF-8').'</li>'.'</a>'.'</ul>';
}
}
}
}
echo '</ul>'.'</li>';
echo '</ul>';
}
$result=mysqli\u query($link,“SELECT*FROM library WHERE parent\u id=”。$parent\u id=0);
$subResult=mysqli_query($parent_id>,链接“从父库中选择*”);
如果(mysqli_num_行($result)>0){
echo';
while($row=mysqli\u fetch\u数组($result))
{
echo'- '.'。
“
”;
而($sub=mysqli\u fetch\u数组($subResult))
{
如果($row['id']==$sub['parent\u id']))
{
echo$sub['parent_id'];
$subnumitems=mysqli_query($link,'selectmainfolder FROM library WHERE parent_id='。$sub['parent_id']);
$items=mysqli\u fetch\u数组($subnumitems);
foreach($eachItems作为$eachItem){
回显“- ”
”;
}
}
}
}
回音“
”、“”;
回声“”;
}
因为您的要求很好,而且因为我喜欢递归函数的挑战,所以我决定继续帮助您
我最初的回答有点失控,所以我把它清理干净了。我还做了大量的调试,并修复了我在原始帖子中发现的一些“bug”
echo "<pre>"; //preserve whitespace
//I mocked up some arrays ('canned data') to make things easier to show and test
//order of the parents matter ( should be in the order left to right of the menu )
$parents = [
['id' => 1, 'title' => 'item1', 'link' => 'http://www.example.com/item1', 'parent_id' => 0],
['id' => 8, 'title' => 'item8', 'link' => 'http://www.example.com/item8', 'parent_id' => 0],
];
var_export( $parents );
echo "\n\n";
//you can order children any way you want, they will still be grouped under the right parent
$children = [
['id' => 2, 'title' => 'item2', 'link' => 'http://www.example.com/item2', 'parent_id' => 1],
['id' => 3, 'title' => 'item3', 'link' => 'http://www.example.com/item3', 'parent_id' => 2],
['id' => 4, 'title' => 'item4', 'link' => 'http://www.example.com/item4', 'parent_id' => 1], //not ordered
['id' => 5, 'title' => 'item5', 'link' => 'http://www.example.com/item5', 'parent_id' => 2, "target" => null, "css_class" => null],
['id' => 6, 'title' => 'item6', 'link' => 'http://www.example.com/item6', 'parent_id' => 1, "target" => "_blank"],
['id' => 7, 'title' => 'item7', 'link' => 'http://www.example.com/item7', 'parent_id' => 8, "css_class"=>"test"],
];
var_export($children);
echo "\n\n";
$lv = 1;
$html = "<ul class=\"menu menu_lv0\" >\n";
foreach( $parents AS &$parent ){
$html = buildMenuTree( $parent, $children, $html, $lv, $lv ); //pass by refrence so no return needed
}
$html .= "</ul>\n";
var_export( $parents );
echo "\n\n";
echo htmlspecialchars( $html )."\n\n"; //htmlspecialchars for display reasons
//=========================================
// DEFINE FUNCTION
//=========================================
//$parent is passed by refrence
function buildMenuTree( &$parent, $children, $html='', $lv=0, $indent=0 ){
if( $lv == 1 || $lv == 2) $mode = true;
if( !$children ) return;
reset( $children ); //reset the array
$t0 = getIndent( $indent );
$t1 = getIndent( ($indent+1) );
//css class for menu item
$css_class = (isset($parent['css_class']) && $parent['css_class']) ? " {$parent['css_class']}" : "";
//link target
$target = (isset($parent['target']) && $parent['target']) ? "target=\"{$parent['target']}\" " : "";
$id = $parent['id'];
$html .= "{$t0}<li id=\"menu_item_{$id}\" class=\"menu_item item_lv{$lv}{$css_class}\">\n";
$html .= "{$t1}<a class=\"menu_link\" href=\"{$parent['link']}\" {$target}>{$parent['title']}</a>";
while( false !== ( $child = current( $children ) ) ){
//if the parents id, matches the childs parent id, then add the current child
//as a child of parent and check it ( current child ) for any children it may have
// add if( ... && $limit == $lv) and pass in a $limit param to the function to limit the depth
if( $parent['id'] == $child['parent_id'] ){
$key = key( $children );
//remove - to reduce array and our processing time, we can remove the current item
//also the current item is the parent in the recusive function and therefore we
//know it cannot be a child of itself and we wont need it in that branch
unset( $children[$key] );
//make a recursive call ( call this method again
//&$parent, $children, $html='', $lv=1, $indent=1
$r_html = buildMenuTree($child, $children, "", ($lv + 1), ($indent+2));
//creante the children array if not exists
if( !isset( $parent['children'] ) ){
$parent['children'] = [];
$html .= "\n{$t1}<ul class=\"sub_menu menu_lv{$lv} parent_{$parent['id']}\" >\n";
$html .= $r_html;
}else{
$html .= $r_html;
}
///store the child
$parent['children'][] = $child;
}else{
$next = next( $children );
};
}
if( !isset( $parent['children'] ) )
$html .= "\n";
else
$html .= "{$t1}</ul>\n";
$html .= "{$t0}</li>\n";
return $html;
}
function getIndent( $indent, $pad = " " ){
return str_pad("", ( $indent * 4 ), $pad);
}
echo "</pre>";
HTML
菜单
-
-
-
我冒昧地添加了一些我认为是通常实现的导航菜单的特性。
- CSS类,如果一行包含
,则$row['CSS_Class']
会将其值添加到它的类中,您可以将其设置为
或干脆不包含它李>false | null
- 目标,如果项目包含
$row['Target']
祝你好运,祝你愉快 您需要一个树结构和一个递归的“walker”类型函数来正确嵌套对象。查找
,嵌套集
或邻接列表
层次化数据结构。一旦您获得层次结构中的数据,那么您将需要一个函数(可能是递归函数)来构建物化路径
集,然后是一些适当的CSS,这不是世界上最容易做到的事情。。。lolparent\u id=$parent\u id=0-这一点你都不觉得奇怪?我觉得很好,ul>li
它可以工作。。。我认为这是没有意义的,因为在任何情况下,执行两个简单的查询都不会得到多层嵌套树。我所有的主菜单项都有parent_id=0,所以我只是简单地选择它们。如果我能让大家看看桌子,那就容易多了。嗨,谢谢你,真的很感谢你的努力。我还没有让它工作,但这是一个进步。在逐行将其添加到我的代码之后。我觉得我添加的数据是错误的,因为当我在传入任何函数之前回显$parents数组时,我得到了以下输出:Array11Item1 Item100当在gettreecursive()之前的foreach函数中使用echo with时,我得到了以下结果:array(0=>1',id=>1',1=>Item 1',mainfolder'=>Item 1',2=>0',parent\u id'=>0',)“”以及此im收到错误:非法字符串偏移量“id”和“parent_id”。因此,我已通过从元素中删除引号和[]修复了非法偏移量问题。不太清楚我为什么要这么做。但是现在html上没有显示任何内容。不过没有警告。我想我更希望你对这个数组的第一个注释是一条记录,当你想要很多记录时,你应该有“。。。。父项_id='。($parent_id=0)
而且你没有在你的查询中设置fetch模式,所以你得到了一个数字数组和一个你想要使用的关联数组[0=>['id'=>1,…]
而不是mysqli\u fetch\u assoc()
mysqli\u fetch\u array()
$parent = array ( 0 => array ( 'id' => 1, 'title' => 'item1', 'link' => 'http://www.example.com/item1', 'parent_id' => 0, 'children' => array ( 0 => array ( 'id' => 2, 'title' => 'item2', 'link' => 'http://www.example.com/item2', 'parent_id' => 1, 'children' => array ( 0 => array ( 'id' => 3, 'title' => 'item3', 'link' => 'http://www.example.com/item3', 'parent_id' => 2, ), 1 => array ( 'id' => 5, 'title' => 'item5', 'link' => 'http://www.example.com/item5', 'parent_id' => 2, 'target' => NULL, 'css_class' => NULL, ), ), ), 1 => array ( 'id' => 4, 'title' => 'item4', 'link' => 'http://www.example.com/item4', 'parent_id' => 1, ), 2 => array ( 'id' => 6, 'title' => 'item6', 'link' => 'http://www.example.com/item6', 'parent_id' => 1, 'target' => '_blank', ), ), ), 1 => array ( 'id' => 8, 'title' => 'item8', 'link' => 'http://www.example.com/item8', 'parent_id' => 0, 'children' => array ( 0 => array ( 'id' => 7, 'title' => 'item7', 'link' => 'http://www.example.com/item7', 'parent_id' => 8, 'css_class' => 'test', ), ), ), )
<ul class="menu menu_lv0" > <li id="menu_item_1" class="menu_item item_lv1"> <a class="menu_link" href="http://www.example.com/item1" >item1</a> <ul class="sub_menu menu_lv1 parent_1" > <li id="menu_item_2" class="menu_item item_lv2"> <a class="menu_link" href="http://www.example.com/item2" >item2</a> <ul class="sub_menu menu_lv2 parent_2" > <li id="menu_item_3" class="menu_item item_lv3"> <a class="menu_link" href="http://www.example.com/item3" >item3</a> </li> <li id="menu_item_5" class="menu_item item_lv3"> <a class="menu_link" href="http://www.example.com/item5" >item5</a> </li> </ul> </li> <li id="menu_item_4" class="menu_item item_lv2"> <a class="menu_link" href="http://www.example.com/item4" >item4</a> </li> <li id="menu_item_6" class="menu_item item_lv2"> <a class="menu_link" href="http://www.example.com/item6" target="_blank" >item6</a> </li> </ul> </li> <li id="menu_item_8" class="menu_item item_lv1"> <a class="menu_link" href="http://www.example.com/item8" >item8</a> <ul class="sub_menu menu_lv1 parent_8" > <li id="menu_item_7" class="menu_item item_lv2 test"> <a class="menu_link" href="http://www.example.com/item7" >item7</a> </li> </ul> </li> </ul>