多级菜单层级动态递增异常:PHP菜单渲染代码调试
I see the issue with your recursive menu level logic—let's fix this step by step! The core problem is how you're incrementing the $level variable inside the loop, which breaks the hierarchy for sibling menu items. Here's a detailed breakdown and corrected solution:
Key Problems in Your Original Code
- Using
$level++modifies the original$levelvalue for every sibling menu, causing incorrect level counts for subsequent items. - The sub-menu class only checks if
parent_id > 0, not the actual level, which limits styling flexibility for deeper nested menus.
Corrected Recursive Function
This version fixes the level logic, adds dynamic styling hooks, and includes critical security improvements:
function admin_menus($parent_id = 0, $level = 1) { global $conn; // Use prepared statements to avoid SQL injection (essential for security!) $query = "SELECT * FROM menus WHERE parent_id = ? ORDER BY position"; $stmt = mysqli_prepare($conn, $query); mysqli_stmt_bind_param($stmt, "i", $parent_id); mysqli_stmt_execute($stmt); $menus = mysqli_stmt_get_result($stmt); confirmQuery($menus); if(mysqli_num_rows($menus) > 0) { while($row = mysqli_fetch_assoc($menus)) { $menu_id = $row['id']; $menu_title = $row['title']; $menu_position = $row['position']; // Dynamic class for each level (e.g., menu-level-1, menu-level-3) $level_class = "menu-level-" . $level; // Show sub-menu indicators for levels 2 and above $sub_menu = $level > 1 ? "sub-menu" : ""; $sub_icon = $level > 1 ? "<i class='fa fa-angle-right pr-10'></i>" : ""; echo "<tr class='$level_class' data-index='$menu_id' data-position='$menu_position'>"; echo "<td>"; echo "<div class='$sub_menu'>"; echo $sub_icon; echo "<a href='menus.php?source=edit_menu&m_id=$menu_id'>"; echo htmlspecialchars($menu_title); // Escape output to prevent XSS attacks echo "</a>"; echo "</div>"; echo "</td>"; echo "<td>"; echo "<div class='dropdown text-center'>"; echo "<button class='btn btn-sm btn-primary dropdown-toggle' type='button' id='dropdownAction-$menu_id' data-toggle='dropdown' aria-haspop='true' aria-expanded='false'>"; echo "<i class='fa fa-cogs'></i>"; echo "</button>"; echo "<div class='dropdown-menu dropdown-menu-right' aria-labelledby='dropdownAction-$menu_id'>"; echo "<a href='menus.php?source=edit_menu&m_id=$menu_id' class='dropdown-item'>Edit</a>"; echo "<a href='menus.php?delete=$menu_id' class='dropdown-item'>Delete</a>"; echo "</div>"; echo "</div>"; echo "</td>"; echo "</tr>"; // Pass level + 1 to child menus without modifying the original $level admin_menus($menu_id, $level + 1); } } }
What Changed & Why
- Proper Level Increment: Instead of altering the parent
$levelvariable, we pass$level + 1directly to the recursive call. This keeps the original level value intact for sibling items, ensuring accurate hierarchy tracking. - Dynamic Level Classes: The
menu-level-$levelclass lets you target any menu level with CSS, including future nested levels you might add later. - Security Updates: Added prepared statements to block SQL injection, and
htmlspecialchars()to escape menu titles and prevent XSS vulnerabilities. - Unique Dropdown IDs: Appended
-$menu_idto dropdown button IDs to avoid duplicate IDs on the page, which fixes Bootstrap dropdown functionality for multiple menu items.
Example CSS for Multi-Level Styling
Now you can style each level independently, and new levels will automatically fit the pattern:
/* Level 1 (Top-level menus: Home, About, Product, Contact) */ .menu-level-1 td div { font-weight: bold; padding-left: 0; } /* Level 2 (Child of Product: Watches, Tops, Pants) */ .menu-level-2 td div { padding-left: 20px; color: #555; } /* Level 3 (Child of Watches: Rolex, Some other watch) */ .menu-level-3 td div { padding-left: 40px; color: #777; font-style: italic; } /* Add styles for future levels as needed */ .menu-level-4 td div { padding-left: 60px; color: #999; }
This setup will correctly map your menu structure to the right levels, and it’s fully scalable for any additional nested menus you add later.
内容的提问来源于stack exchange,提问作者KittyKat
相关产品推荐
相关产品推荐

