动态菜单 php bootstrap mysql [英] Dynamic menu php bootstrap mysql
问题描述
我对这段代码有问题,我可以有第一级,在第二级我有一个 id 号,而 3eme 级什么都没有.
我需要查找 4 个深度级别的信息
代码也会产生错误:Illegal string offset 'label'
在这一行:
foreach($menu_sub[$submenus['sub_menu']] as $sub2_key => $submenus2) {
结果
索引---- 8- - - - - 没有出现- - - - - 没有出现---- 3---- 2- - 一世配置---- 9- - - - - 没有出现- - - - - 没有出现----1----1----男----1目录
数据库
CREATE TABLE `administrator_menu` (`id` int(11) 非空,`link` 中文本不为空,`parent_id` int(11) 非空,`sort_order` int(11) 非空,`class` varchar(255) 非空) 引擎=InnoDB 默认字符集=latin1;——-- 转储表`administrator_menu`的数据——插入`administrator_menu`(`id`、`link`、`parent_id`、`sort_order`、`class`)值(1, '', 0, 2, ''),(3, '', 0, 1, ''),(5, '', 0, 3, ''),(6, '', 0, 4, ''),(7, '', 3, 1, ''),(8, '', 3, 2, ''),(9, '', 1, 1, ''),(10, '', 9, 0, '');更改表`administrator_menu`添加主键 (`id`);更改表`administrator_menu`修改`id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=11;创建表`administrator_menu_description`(`id` int(11) 非空,`label` varchar(255) 非空,`language_id` int(11) NOT NULL DEFAULT '1') 引擎=InnoDB 默认字符集=latin1;——-- 转储表`administrator_menu_description`的数据——插入`administrator_menu_description`(`id`、`label`、`language_id`)值(3, 'Accueil', 1),(7, '管理', 1),(7, '管理', 2),(5, '目录', 2),(5, '目录', 1),(1, '配置', 1),(1, '配置', 2),(10, '一般配置', 1),(10, '一般配置', 2),(3, '索引', 2),(8, '索引目录', 1),(8, '索引商店', 2),(9, '马精品', 1),(9, '我的商店', 2);更改表`administrator_menu_description`添加主键 (`id`,`language_id`),添加密钥`标签`(`标签`);更改表`administrator_menu_description`修改`id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=11;
脚本
sql请求结果
表administrator_menuid parent_id sort_order 类1 0 23 0 15 0 36 0 47 3 18 3 29 1 110 9 0
注意:parent_id 是选择创建分层菜单的 id 数例如 id = 10
和 parent_id = 9
,我们在 3em 级别
例如 id = 9
和 parent_id = 1
,我们在 2em 级别
例如 id = 1
和 parent_id = 0
,我们在第一层
表格描述菜单id 标签 language_id1 配置 11 配置 23 开始 13 索引 25 目录 15 目录 27 管理 17 管理 28 索引目录 18 指数店 29麻精品19 我的店铺 210 配置概述 110 一般配置2<?php//从菜单表中选择所有条目$Qmenus = $Db->prepare('SELECT a.id,一条链接,a.parent_id,一类,a.sort_order,标签FROM :table_administrator_menu a,:table_administrator_menu_description amd其中 a.id = amd.id和 amd.language_id = :language_idORDER BY a.parent_id,a.sort_order');$Qmenus->bindInt(':language_id', $Language->getId());$Qmenus->execute();$Qmenus = $Qmenus->fetchAll();?><!-- 导航--><nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0"><div class="navbar-default sidebar" role="navigation"><div class="sidebar-nav navbar-collapse"><ul class="nav" id="side-menu"><?php$menu_parent = array();$menu_sub = array();foreach ($Qmenus 作为 $menus) {如果($menus['parent_id'] == 0){$menu_parent[$menus['id']] = $menus;} 别的 {如果(isset($menu_parent[$menus['parent_id']])){$menu_parent[$menus['parent_id']]['sub_menu'] = $menus['id'];$menu_sub[$menus['id']] = $menus;} else if (isset($menu_sub[$menus['parent_id']])) {$menu_sub[$menus['parent_id']]['sub_menu'] = $menus['id'];$menu_sub[$menus['id']] = $menus;}}}foreach($menu_parent as $key => $menus) {echo '<li><a href="#"><i class="fa fa-sitemap fa-fw"></i>'.$menus['label'] .'<span class="fa arrow"></span></a>';if (!empty($menus['sub_menu'])) {echo '
<!--/.sidebar-collapse -->
<!--/.navbar-static-side --></nav>
你的代码只会生成两级菜单,如果你需要通过任何你想要的级别,我认为你需要使用递归.
这是一个基于您的数据库结构和示例的示例.在示例中我们将生成一个不同级别的菜单,英文标签用于菜单项名称.
prepare(" SELECT * FROM管理员菜单、管理员菜单_描述其中administrator_menu.id = administrator_menu_description.id和 language_id = 2和 parent_id = $parent");$m->execute();foreach ($m->fetchAll() as $menu_row) {$m = $db->prepare("SELECT count(*) FROM administrator_menu where parent_id = $menu_row[id]");$m->execute();//该项目是父项,所以再次递归if($m->fetchAll()[0][0] !=='0' && $level !== 0){echo "".$menu_row['label']."";drawMenu($db, $menu_row[0], $level - 1);echo "</ul></li>";}else{//项目是叶子或者我们到达了最终级别,即基本情况,所以打印项目标签echo "- ".$menu_row['label'] ."</li>";}}}?><!DOCTYPE html><头><title></title>头部><身体><?phpecho "<div> <ul>";drawMenu($db, 0, null);//所有级别echo "</ul></div>";echo "--------------------------------------------------------";echo "<div> <ul>";drawMenu($db, 0, 0);//级别 0echo "</ul></div>";echo "--------------------------------------------------------";echo "<div> <ul>";drawMenu($db, 0, 1);//1级echo "</ul></div>";echo "--------------------------------------------------------";echo "<div> <ul>";drawMenu($db, 0, 2);//级别 2echo "</ul></div>";?></html>
绘制所有级别:
echo " ";drawMenu($db, 0, null);//所有级别echo "</ul></div>";drawMenu
函数的工作原理如下:
- 首先,我们传递一个
$db
对象来进行数据库查询,$parent
树将从中开始,$level
用于级别的树. - 该函数将首先选择给定
$parent
的孩子,然后为每个 foreach ($m->fetchAll() as $menu_row) {...}
. 在循环中我们有两种情况:
项目是叶子,即不是其他项目的父项,或者我们到达树的最终级别.这种情况称为基本情况,其中递归将停止并返回一个值echo "- ".$menu_row['label'] ."</li>";
该项是父项,在这种情况下,我们再次调用 drawMenu
函数,将项 id $menu_row[0]
作为父项和 $level - 1
确保到达关卡结束时停止.
测试代码并进行更改以满足您的需要.
I have a problem with this code, And I can have the 1st level, On the second level I have an id number and the 3eme level nothing.
I need to find informations on 4 levels of deep
Also the code produce an error : Illegal string offset 'label'
on this line :
foreach($menu_sub[$submenus['sub_menu']] as $sub2_key => $submenus2) {
result
index
---- 8
--------- not appear
--------- not appear
---- 3
---- 2
---- I
Configuration
---- 9
--------- not appear
--------- not appear
----1
----1
----M
----1
Catalogue
The DB
CREATE TABLE `administrator_menu` (
`id` int(11) NOT NULL,
`link` mediumtext NOT NULL,
`parent_id` int(11) NOT NULL,
`sort_order` int(11) NOT NULL,
`class` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Dumping data for table `administrator_menu`
--
INSERT INTO `administrator_menu` (`id`, `link`, `parent_id`, `sort_order`, `class`) VALUES
(1, '', 0, 2, ''),
(3, '', 0, 1, ''),
(5, '', 0, 3, ''),
(6, '', 0, 4, ''),
(7, '', 3, 1, ''),
(8, '', 3, 2, ''),
(9, '', 1, 1, ''),
(10, '', 9, 0, '');
ALTER TABLE `administrator_menu`
ADD PRIMARY KEY (`id`);
ALTER TABLE `administrator_menu`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=11;
CREATE TABLE `administrator_menu_description` (
`id` int(11) NOT NULL,
`label` varchar(255) NOT NULL,
`language_id` int(11) NOT NULL DEFAULT '1'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Dumping data for table `administrator_menu_description`
--
INSERT INTO `administrator_menu_description` (`id`, `label`, `language_id`) VALUES
(3, 'Accueil', 1),
(7, 'Administration', 1),
(7, 'Administration', 2),
(5, 'Catalog', 2),
(5, 'Catalogue', 1),
(1, 'Configuration', 1),
(1, 'Configuration', 2),
(10, 'Configuration générale', 1),
(10, 'general Configuration', 2),
(3, 'Index', 2),
(8, 'Index Catalogue', 1),
(8, 'Index Shop', 2),
(9, 'Ma boutique', 1),
(9, 'My shop', 2);
ALTER TABLE `administrator_menu_description`
ADD PRIMARY KEY (`id`,`language_id`),
ADD KEY `label` (`label`);
ALTER TABLE `administrator_menu_description`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=11;
the script
result of sql request
table administrator_menu
id parent_id sort_order class
1 0 2
3 0 1
5 0 3
6 0 4
7 3 1
8 3 2
9 1 1
10 9 0
Note :
parent_id is the number of id selected to create an hierarchical menu
For example the id = 10
and parent_id = 9
, we are on the 3em level
For example the id = 9
and parent_id = 1
, we are on the 2em level
For example the id = 1
and parent_id = 0
, we are on the 1st level
table description menu
id lable language_id
1 Configuration 1
1 Configuration 2
3 Accueil 1
3 Index 2
5 Catalogue 1
5 Catalog 2
7 Administration 1
7 Administration 2
8 Index Catalogue 1
8 Index Shop 2
9 Ma boutique 1
9 My shop 2
10 Configuration générale 1
10 general Configuration 2
<?php
// Select all entries from the menu table
$Qmenus = $Db->prepare('SELECT a.id,
a.link,
a.parent_id,
a.class,
a.sort_order,
amd.label
FROM :table_administrator_menu a,
:table_administrator_menu_description amd
where a.id = amd.id
and amd.language_id = :language_id
ORDER BY a.parent_id,
a.sort_order
');
$Qmenus->bindInt(':language_id', $Language->getId());
$Qmenus->execute();
$Qmenus = $Qmenus->fetchAll();
?>
<!-- Navigation -->
<nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0">
<div class="navbar-default sidebar" role="navigation">
<div class="sidebar-nav navbar-collapse">
<ul class="nav" id="side-menu">
<?php
$menu_parent = array();
$menu_sub = array();
foreach ($Qmenus as $menus) {
if ($menus['parent_id'] == 0) {
$menu_parent[$menus['id']] = $menus;
} else {
if (isset($menu_parent[ $menus['parent_id']])) {
$menu_parent[$menus['parent_id']]['sub_menu'] = $menus['id'];
$menu_sub[$menus['id']] = $menus;
} else if (isset($menu_sub[$menus['parent_id']])) {
$menu_sub[$menus['parent_id']]['sub_menu'] = $menus['id'];
$menu_sub[$menus['id']] = $menus;
}
}
}
foreach($menu_parent as $key => $menus) {
echo '<li><a href="#"><i class="fa fa-sitemap fa-fw"></i>' . $menus['label'] . '<span class="fa arrow"></span></a>';
if (!empty($menus['sub_menu'])) {
echo '<ul class="nav nav-second-level">';
foreach($menu_sub[$menus['sub_menu']] as $sub_key => $submenus) {
echo '<li><a href="#">' . $submenus['label'] . '</a>';
if (!empty($submenus['sub_menu'])) {
foreach($menu_sub[$submenus['sub_menu']] as $sub2_key => $submenus2) {
echo '<li><a href="#">' . $submenus2['label'] . '</a>';
if (!empty($submenus2['sub_menu'])) {
foreach($menu_sub[$submenus2['sub_menu']] as $sub3_key => $submenus3) {
echo '<li><a href="#">' . $submenus3['label'] . '</a></li>';
}
}
echo '</li>';
}
}
echo '</li>';
}
echo '</ul>';
}
echo '</li>';
}
?>
</ul>
</div>
<!-- /.sidebar-collapse -->
</div>
<!-- /.navbar-static-side -->
</nav>
解决方案 Your code will only generate two level menu, if you need to go through any level you want, i think that you need to use recursion.
Here is an example based on your database structure and samples. In the example we will generate a menu in different levels, the English labels are used for menu items names.
<?php
$db = new PDO('mysql:host=localhost;dbname=testdb', 'root', '');
function drawMenu($db, $parent, $level = null){
$m = $db->prepare(" SELECT * FROM
administrator_menu, administrator_menu_description
where administrator_menu.id = administrator_menu_description.id
and language_id = 2
and parent_id = $parent");
$m->execute();
foreach ($m->fetchAll() as $menu_row) {
$m = $db->prepare("SELECT count(*) FROM administrator_menu where parent_id = $menu_row[id]");
$m->execute();
// The item is parent, so do recursion again
if($m->fetchAll()[0][0] !== '0' && $level !== 0){
echo "<li>" . $menu_row['label']."<ul>";
drawMenu($db, $menu_row[0], $level - 1);
echo "</ul></li>";
}else{ // The item is a leaf or we reach the end level, i.e. base case, so do print the item label
echo "<li>" . $menu_row['label'] . "</li>";
}
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<?php
echo "<div> <ul>";
drawMenu($db, 0, null); // all levels
echo "</ul></div>";
echo "--------------------------------------------------------";
echo "<div> <ul>";
drawMenu($db, 0, 0); // level 0
echo "</ul></div>";
echo "--------------------------------------------------------";
echo "<div> <ul>";
drawMenu($db, 0, 1); // level 1
echo "</ul></div>";
echo "--------------------------------------------------------";
echo "<div> <ul>";
drawMenu($db, 0, 2); // level 2
echo "</ul></div>";
?>
</body>
</html>
To draw all levels:
echo "<div> <ul>";
drawMenu($db, 0, null); // all levels
echo "</ul></div>";
The drawMenu
function works as following:
- First we pass a
$db
object to make database queries, $parent
that the tree will start with and $level
for the level of the tree.
- The function will start by selecting the child of the given
$parent
and go in loop for each one foreach ($m->fetchAll() as $menu_row) {...}
.
In the loop we have two cases:
The item is a leaf i.e. not a parent for other items, or we reach the final level of tree. This case is call the Base case, in which the recursion will stop and return a value echo "<li>" . $menu_row['label'] . "</li>";
The item is a parent, in this case we call the drawMenu
function again with the item id $menu_row[0]
as a parent and $level - 1
to make sure to stop when reach the end of levels.
Test the code and change it to fit your needs.
这篇关于动态菜单 php bootstrap mysql的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文