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

PHP 實現多級樹型菜單:基於 MySQL 遞歸輸出與前端交互

     編輯:PHP 綜合知識

數據庫設計

單表 menu 存儲所有層級菜單項,採用鄰接表模型:

CREATE TABLE menu (
    menu_id INT(11) NOT NULL AUTO_INCREMENT,
    menu VARCHAR(20) NOT NULL,
    menu_grade INT(11) NOT NULL,      -- 1=主菜單, 2=二級, 3=三級...
    menu_superior INT(11) NOT NULL,   -- 父級 menu_id, 0 表示頂級
    PRIMARY KEY (menu_id)
);

示例數據構建:計算機→編程→PHP與MySQL→php/mysql;數學→高等數學→線性代數/離散數學;文學→中國文學 等多層結構。

核心遞歸函數

<?php
function my_menu($menu_content, $i, $menu_grade_temp, $menu_superior_temp) {
    global $PHP_SELF;
    $temp1 = $menu_grade_temp + 1; // 下一級層級
    $menu_superior_temp_array = explode("/", $menu_superior_temp); // 父級路徑數組

    for ($t = 0; $t < $i; $t++) {
        $menu_array = explode("/", $menu_content[$t]); // [id, name, grade, superior]
        // 匹配當前層級且父級ID符合
        if (($menu_array[2] == $menu_grade_temp) &&
            ($menu_array[3] == $menu_superior_temp_array[$menu_grade_temp - 1])) {

            // 縮進顯示
            for ($p = 1; $p <= $menu_grade_temp; $p++) { echo "  "; }

            $temp3 = $menu_superior_temp_array;
            $temp3[$menu_grade_temp] = $menu_array[0]; // 當前ID作為下一級父級
            $temp2 = implode("/", $temp3);

            // 判斷是否為當前展開節點
            if ($menu_array[0] == $menu_superior_temp_array[$temp1 - 1]) {
                $temp5 = $temp1 - 1;
                $temp3[$menu_grade_temp] = "";
                $temp6 = implode("/", $temp3);
                echo "<a href=\"$PHP_SELF?menu_grade_temp=$temp5&menu_superior_temp=$temp6\">{$menu_array[1]}</a><br>";
                my_menu($menu_content, $i, $temp1, $temp2); // 遞歸輸出子菜單
            } else {
                $temp3[$menu_grade_temp + 1] = "";
                $temp6 = implode("/", $temp3);
                echo "<a href=\"$PHP_SELF?menu_grade_temp=$temp1&menu_superior_temp=$temp6\">{$menu_array[1]}</a><br>";
            }
        }
    }
}

// 初始化並調用
if ($menu_grade_temp == "") { $menu_superior_temp = 0; }
$i = 0;
while (list($menu_id, $menu, $menu_grade, $menu_superior) = mysql_fetch_row($db_data)) {
    $menu_content[$i] = "$menu_id/$menu/$menu_grade/$menu_superior";
    $i++;
}
my_menu($menu_content, $i, 1, $menu_superior_temp);
?>

交互原理

  • URL 參數 menu_grade_temp 表示即將展開的層級,menu_superior_temp 為各層級父級ID路徑 (如 0/1/2/)
  • 點擊菜單項 → 刷新頁面 → 遞歸函數根據參數決定哪一分支展開子級
  • 縮進用    視覺化層級

優缺點評析

優點缺點
單表簡單,無需遞歸 CTE 或巢狀集合查詢所有行再 PHP 端過濾,數據量大時效率低
邏輯集中在一個遞歸函數,易理解URL 參數冗長,狀態攜帶在客戶端,不利 SEO/分享
無需 JavaScript 即可實現展開/折疊每次點擊整頁刷新,用戶體驗差

現代化改進方案

  1. 數據庫端遞歸查詢 (MySQL 8.0+):WITH RECURSIVE cte AS (...) SELECT ... 一次取得完整樹
  2. 前端渲染:API 返回 JSON 樹,前端用 <ul><li> + CSS/JS (如 zTree, jstree, Vue/React 遞歸組件) 實現無刷新展開、拖拽排序、懶加載
  3. 路徑枚舉/閉包表:讀取子樹 O(1),寫入稍複雜,適合高頻讀場景
  4. 緩存:菜單變動少,Redis/文件緩存整棵樹 JSON

總結

代碼展示了早期 PHP 「後端遞歸拼 HTML」的典型模式。理解鄰接表模型與遞歸遍歷是基礎;現代開發應採用「後端輸出樹狀 JSON + 前端組件化渲染」架構,分離關注點,提升體驗與性能。

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