首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP+MySQL遞歸實現無限級動態樹型菜單:數據結構與前端交互完整方案

     編輯:PHP 相關知識

樹型菜單在桌面應用普遍,Web端受限於無現成組件,常用JavaScript硬編碼實現,擴展性差。本文展示如何結合PHP遞歸函數、MySQL遞歸數據結構、JavaScript交互,構建無級數限制、數據驅動的動態樹型菜單。

數據庫設計:遞歸關聯模型

CREATE TABLE menu (
    id TINYINT(4) NOT NULL AUTO_INCREMENT,
    parent_id TINYINT(4) DEFAULT 0 NOT NULL,
    name VARCHAR(20) NOT NULL,
    url VARCHAR(60) DEFAULT '',
    PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

字段含義:

  • id:主鍵
  • parent_id:父菜單ID,頂級為0
  • name:顯示名稱
  • url:葉子節點鏈接,非葉子為空

測試數據

INSERT INTO menu VALUES
(1, 0, '人事管理', ''),
(2, 0, '通訊交流', ''),
(3, 1, '檔案管理', ''),
(4, 1, '考勤管理', 'https://localhost/personal/attendance.php'),
(5, 2, '通訊錄', ''),
(6, 2, '網絡會議', ''),
(7, 3, '新增檔案', 'https://localhost/personal/add_achive.php'),
(8, 3, '查詢檔案', 'https://localhost/personal/search_archive.php'),
(9, 3, '刪除檔案', 'https://localhost/personal/delete_archive.php'),
(10, 5, '新增通訊記錄', 'https://localhost/communication/add_address.php'),
(11, 5, '查詢通訊記錄', 'https://localhost/communication/search_address.php'),
(12, 5, '刪除通訊記錄', 'https://localhost/communication/delete_address.php'),
(13, 6, '召開會議', 'https://localhost/communication/convence_meeting.php'),
(14, 6, '會議查詢', 'https://localhost/communication/search_meeting.php');

PHP遞歸生成HTML

<?php
function buildMenu($parent_id = 0, $level = 0) {
    global $pdo;
    $stmt = $pdo->prepare("SELECT * FROM menu WHERE parent_id = ? ORDER BY id");
    $stmt->execute([$parent_id]);
    $items = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    if (empty($items)) return '';
    
    $html = $level === 0 ? '<ul class="tree-menu">' : '<ul style="display:none;">';
    foreach ($items as $item) {
        $has_children = hasChildren($item['id']);
        $html .= '<li>';
        if ($has_children) {
            $html .= '<span class="toggle" data-menu="' . $item['id'] . '">' . htmlspecialchars($item['name']) . '</span>';
            $html .= buildMenu($item['id'], $level + 1);
        } else {
            $html .= '<a href="' . htmlspecialchars($item['url']) . '" target="_blank">' . htmlspecialchars($item['name']) . '</a>';
        }
        $html .= '</li>';
    }
    $html .= '</ul>';
    return $html;
}

function hasChildren($id) {
    global $pdo;
    $stmt = $pdo->prepare("SELECT 1 FROM menu WHERE parent_id = ? LIMIT 1");
    $stmt->execute([$id]);
    return (bool)$stmt->fetchColumn();
}

echo buildMenu();

JavaScript交互邏輯

<script>
document.addEventListener('click', function(e) {
    if (e.target.matches('.toggle')) {
        const menuId = e.target.dataset.menu;
        const subMenu = document.querySelector(`ul[data-parent="${menuId}"]`);
        if (subMenu) {
            subMenu.style.display = subMenu.style.display === 'none' ? 'block' : 'none';
            e.target.classList.toggle('expanded');
        }
    }
});
</script>

CSS樣式要點

.tree-menu { list-style: none; padding-left: 20px; margin: 0; }
.tree-menu li { position: relative; }
.toggle { cursor: pointer; user-select: none; }
.toggle::before { content: '▶ '; display: inline-block; transition: transform .2s; }
.toggle.expanded::before { transform: rotate(90deg); }
.tree-menu a { text-decoration: none; color: #333; }
.tree-menu a:hover { color: #0066cc; }

性能優化與擴展

場景優化方案
菜單項超過百個一次性查詢所有數據,PHP內存中構建樹(遞歸/引用構建),單次查詢
高併發讀取Redis緩存生成的HTML片段,菜單更新時失效
拖拽排序/編輯前端收集順序,批量更新parent_id與sort_order字段
權限控制 JOIN權限表過濾不可見節點,或前端根據權限標識隱藏

遞歸模型簡單直觀,適合中小規模菜單。超大規模或高頻變更場景可考慮嵌套集合模型或閉包表,讀寫性能各有權衡。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved