You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用嵌套do while循环从数据库获取菜单与子菜单?PHP代码求助

解决嵌套do while循环生成导航栏时仅第一个菜单有子菜单的问题

我看了你的代码,问题很明确:你把子菜单的查询语句放在了导航循环的外面,而且只执行了一次,用的是初始的$pageid=1。当第一个导航项循环完后,$cat_query的结果集指针已经走到末尾了,后面的导航项再去循环子菜单时,就没有数据可以取了,所以后面的菜单都没子内容。

问题根源拆解

  • 你在导航循环之前就执行了$cat_sql查询,只获取了nav_id=1的子菜单数据
  • 第一个导航项循环时,已经把$cat_query的结果集全部遍历完了,后续导航项的子菜单循环自然没有数据
  • 每个导航项对应的子菜单应该根据当前导航的nav_id来动态查询,而不是用固定的初始$pageid

解决方案:将子菜单查询移入导航循环内

把获取子菜单的代码放到导航的循环里面,每次循环到一个导航项,就用当前导航的nav_id作为条件去查询对应的子菜单。这样每个导航项都能拿到自己的子菜单数据。

另外,建议用while循环替代do while(避免空结果集时仍输出空标签),同时可以优化代码结构让逻辑更清晰。

修改后的完整代码

<div class="collapse navbar-collapse" id="navbarSupportedContent">
 <ul class="navbar-nav mr-auto">
 <!-- FETCHING NAVIGATION LIST ALONG WITH DROPDOWN MENU FROM DATABASE -->
 <?php
 //SETTING GET PAGES
 if (isset($_GET['nav'])) {
 $pageid = $_GET['nav'];
 }else {
 $pageid = 1;
 }
 //NAVIGATION TABLE QUERY
 $nav_sql = "SELECT * FROM navigation";
 $nav_query = mysqli_query($connection, $nav_sql);

 // 循环遍历所有导航项
 while ($nav_result = mysqli_fetch_assoc($nav_query)) {
 ?>
 <li class="nav-item dropdown">
 <a class="nav-link dropdown-toggle" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" href="?nav=<?php echo $nav_result['nav_id'] ?>">
 <?php echo $nav_result['nav_eng']; ?></a>
 <ul class="dropdown-menu">
 <?php
 // 每次循环导航项时,根据当前nav_id查询对应的子菜单
 $cat_sql = "SELECT * FROM category WHERE nav_id = " . $nav_result['nav_id'];
 $cat_query = mysqli_query($connection, $cat_sql);
 // 循环输出子菜单
 while ($cat_result = mysqli_fetch_assoc($cat_query)) {
 ?>
 <li>
 <a class="dropdown-item" href="?nav=<?php echo $cat_result['cat_id']; ?>"><?php echo $cat_result['cat_eng'] ?></a>
 </li>
 <?php } ?>
 </ul>
 </li>
 <?php } ?>
 </ul>
 </div>

额外优化建议

  1. 防止SQL注入:现在的代码直接把变量拼到SQL里,有注入风险,建议用预处理语句:
// 子菜单查询改成预处理方式
$cat_sql = "SELECT * FROM category WHERE nav_id = ?";
$stmt = mysqli_prepare($connection, $cat_sql);
mysqli_stmt_bind_param($stmt, "i", $nav_result['nav_id']);
mysqli_stmt_execute($stmt);
$cat_query = mysqli_stmt_get_result($stmt);
  1. 减少数据库查询次数:可以先把所有导航和子菜单数据一次性取出,整理成关联数组后再循环输出,性能更优:
// 先获取所有导航数据
$nav_list = mysqli_fetch_all($nav_query, MYSQLI_ASSOC);
// 获取所有子菜单并按nav_id分组
$cat_sql = "SELECT * FROM category";
$cat_query = mysqli_query($connection, $cat_sql);
$cat_groups = [];
while ($cat = mysqli_fetch_assoc($cat_query)) {
    $cat_groups[$cat['nav_id']][] = $cat;
}
// 循环导航并输出子菜单
foreach ($nav_list as $nav) {
    // 输出导航项代码...
    // 直接从分组数组中取对应子菜单
    $sub_cats = $cat_groups[$nav['nav_id']] ?? [];
    foreach ($sub_cats as $cat) {
        // 输出子菜单代码...
    }
}

内容的提问来源于stack exchange,提问作者user12210515

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:54:11