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

数据库驱动多级菜单子菜单不显示问题求助

解决二级/三级子菜单无法显示的问题

我帮你梳理下代码里的几个关键问题,这些应该是导致子菜单不显示的主要原因:

一、PHP代码中的核心问题及修正

你的递归函数里存在几个破坏HTML结构和逻辑的问题:

1. 重复创建数据库连接

每次调用display_children都会新建一个数据库连接,这不仅效率低下,还可能导致连接资源耗尽。应该把连接逻辑移到函数外部,或者通过参数传入连接对象。

2. HTML标签闭合错误

函数末尾你写了echo "</ul><nav>";,这里把</nav>写成了<nav>,会导致HTML结构嵌套混乱,浏览器无法正确解析子菜单的层级。

3. 不必要的echo函数调用

最后一行echo display_children(0, 1);,但display_children函数内部已经直接输出HTML了,函数本身没有返回值,这会额外输出一个null,破坏页面结构,应该直接调用display_children(0, 1);。

4. SQL注入风险与语法问题

直接把$parent拼进SQL语句里,存在注入风险,而且如果$parent是字符串类型会导致语法错误,应该使用参数化查询。

5. 多余的空else分支

代码里的else;是无效代码,应该删除。

修正后的PHP代码:

<?php
// 先创建一次数据库连接
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "nfs";
$conn = new mysqli($servername, $username, $password, $dbname);

// 检查连接是否成功
if ($conn->connect_error) {
    die("连接失败: " . $conn->connect_error);
}

function display_children($parent, $level, $conn) {
    // 使用参数化查询避免注入
    $stmt = $conn->prepare("SELECT a.cat_id, a.product, a.category_link, Deriv1.Count 
                           FROM `category` a 
                           LEFT OUTER JOIN (SELECT parent_id, COUNT(*) AS Count FROM `category` GROUP BY parent_id) Deriv1 
                           ON a.cat_id = Deriv1.parent_id 
                           WHERE a.parent_id = ?");
    $stmt->bind_param("i", $parent);
    $stmt->execute();
    $result = $stmt->get_result();

    // 只有当有子项时才输出ul,避免空列表
    if ($result->num_rows > 0) {
        echo "<ul class='nav level-$level'>";
        while ($row = mysqli_fetch_assoc($result)) {
            echo "<li><a href='" . htmlspecialchars($row['category_link']) . "'>" . htmlspecialchars($row['product']) . "</a>";
            // 递归调用,传递连接对象
            display_children($row['cat_id'], $level + 1, $conn);
            echo "</li>";
        }
        echo "</ul>";
    }
}

// 直接调用函数,不要echo
echo "<nav>";
display_children(0, 1, $conn);
echo "</nav>";

// 关闭连接
$conn->close();
?>

二、CSS样式缺失导致子菜单不可见

即使PHP输出了正确的层级HTML,如果没有对应的CSS控制子菜单的显示/隐藏,子菜单还是会被隐藏或者布局混乱。这里给你一个基础的CSS示例,实现hover显示子菜单的效果:

/* 基础菜单样式 */
.nav {
    list-style: none;
    padding: 0;
    margin: 0;
    background: #f5f5f5;
    display: flex;
    gap: 1rem;
    position: relative;
}

.nav li {
    position: relative;
    padding: 0.5rem 1rem;
}

/* 子菜单默认隐藏 */
.nav ul {
    list-style: none;
    padding: 0;
    margin: 0;
    position: absolute;
    top: 100%;
    left: 0;
    background: #fff;
    border: 1px solid #ddd;
    display: none;
    min-width: 150px;
}

/* 三级子菜单定位 */
.nav ul ul {
    top: 0;
    left: 100%;
}

/* hover时显示子菜单 */
.nav li:hover > ul {
    display: block;
}

.nav a {
    text-decoration: none;
    color: #333;
}

三、额外检查点

  • 确认数据库中category表的parent_id字段值正确,一级菜单的parent_id是0,二级菜单的parent_id对应父级的cat_id,以此类推。
  • 检查浏览器控制台的HTML结构,确认子菜单的HTML是否已经被正确渲染(如果PHP修正后还是看不到,先看Elements面板里有没有子菜单的代码)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:48:50