使用遞迴實現樹狀選單(無限級分類)

joker丶牧羊人發表於2019-02-19
本期概要:
使用遞迴實現無限級選單分類
複製程式碼

一、資料結構 一般情況下,我們的資料表常規設計如下:

id name pid
1 PHP 技術 0
2 Linux 技術 0
3 PHP 基礎 1
4 PHP 高階 1
5 PHP 資料型別 3
6 PHP 資料型別 - 字串 5
7 Linux 基礎 2
8 Linux 簡單命令 7

當我們從資料庫中查詢出資料,得到二維陣列結構如下:

[
	[
		"id": 1,
		"name": "PHP 技術",
		"pid": 0
	],
	[
		"id": 3,
		"name": "PHP 基礎",
		"pid": 1
	],
	[
		"id": 5,
		"name": "PHP 資料型別",
		"pid": 3
	],
	[
		"id": 6,
		"name": "PHP 資料型別 - 字串",
		"pid": 5
	],
	[
		"id": 4,
		"name": "PHP 高階",
		"pid": 1
	],
	[
		"id": 2,
		"name": "Linux 技術",
		"pid": 0
	],
	[
		"id": 7,
		"name": "Linux 基礎",
		"pid": 2
	],
	[
		"id": 8,
		"name": "Linux 簡單命令",
		"pid": 7
	]
]
複製程式碼

我們要實現無限級選單,主要核心思路就是: 找出每個選單所在的層級(level)
那麼我們就需要用到遞迴,得出每個選單對應的層級

function _infinite($_data, $_pid = 0, $_level = 0) {
    // 定義靜態變數,防止每次都初始化
    static $_new_data = [];
    
    // 迴圈,得出每個資料對應的層級
    foreach ($_data as $_key => $_value) {
        // 第一次遍歷,找到父節點為根節點的節點,即:pid = 0
        if ($_value['pid'] == $_pid) {
            // 當該節點為根節點時,對應的層級設為 0,即:level = 0
            $_value['level'] = $_level;
            // 把該節點放入陣列中
            $_new_data[] = $_value;
            // 得出節點層級後,刪除該節點,減少遞迴的消耗
            unset($_data[$_key]);
            // 開始遞迴,查詢所有 pid 為當前節點 id 的資料,層級加 1,作為對應的子節點
            _infinite($_data, $_value['id'], $_level + 1);
        }
    }

    // 返回帶層級的新陣列
    return $_new_data;
}
複製程式碼

呼叫方法,我們可以得到新陣列:

[
	[
		"id": 1,
		"name": "PHP 技術",
		"pid": 0,
		"level": 0
	],
	[
		"id": 3,
		"name": "PHP 基礎",
		"pid": 1,
		"level": 1
	],
	[
		"id": 5,
		"name": "PHP 資料型別",
		"pid": 3,
		"level": 2
	],
	[
		"id": 6,
		"name": "PHP 資料型別 - 字串",
		"pid": 5,
		"level": 3
	],
	[
		"id": 4,
		"name": "PHP 高階",
		"pid": 1,
		"level": 1
	],
	[
		"id": 2,
		"name": "Linux 技術",
		"pid": 0,
		"level": 0
	],
	[
		"id": 7,
		"name": "Linux 基礎",
		"pid": 2,
		"level": 1
	],
	[
		"id": 8,
		"name": "Linux 簡單命令",
		"pid": 7,
		"level": 2
	]
]
複製程式碼

我們得到新資料以後,需要將資料根據需要的 view 展示出來,我這裡使用樹形結構列印:

function _show_tree($_data) {
    $_html = '';
    foreach ($_data as $_key => $_value) {
        if ($_value['level'] > 0) {
            $_prefix = '|' . str_repeat('--', $_value['level']);
        } else {
            $_prefix = '';
        }

        $_html .= $_prefix . '<a href="###">' . $_value['name'] . '</a><br />';
    }

    return $_html;
}
複製程式碼

得到效果圖如下:

使用遞迴實現樹狀選單(無限級分類)
這樣我們就完成了使用遞迴實現無限級分類的效果。

相關文章