單表 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);
?>
menu_grade_temp 表示即將展開的層級,menu_superior_temp 為各層級父級ID路徑 (如 0/1/2/) 視覺化層級| 優點 | 缺點 |
|---|---|
| 單表簡單,無需遞歸 CTE 或巢狀集合 | 查詢所有行再 PHP 端過濾,數據量大時效率低 |
| 邏輯集中在一個遞歸函數,易理解 | URL 參數冗長,狀態攜帶在客戶端,不利 SEO/分享 |
| 無需 JavaScript 即可實現展開/折疊 | 每次點擊整頁刷新,用戶體驗差 |
WITH RECURSIVE cte AS (...) SELECT ... 一次取得完整樹<ul><li> + CSS/JS (如 zTree, jstree, Vue/React 遞歸組件) 實現無刷新展開、拖拽排序、懶加載代碼展示了早期 PHP 「後端遞歸拼 HTML」的典型模式。理解鄰接表模型與遞歸遍歷是基礎;現代開發應採用「後端輸出樹狀 JSON + 前端組件化渲染」架構,分離關注點,提升體驗與性能。