類設計目標
- 輸入:二維陣列(含 id、pid、title 等字段)。
- 輸出:1) 格式化後的陣列(含層級縮進標識);2) 直接生成 HTML 下拉選單/樹形菜單。
- 支援多選、指定選中項、自定義輸出模板、圖標符號自定義。
核心代碼結構
<?php
class Tree {
public $arr = []; // 原始數據
public $icon = ['│', '├', '└']; // 樹形連接符
private $ret = ''; // 字串輸出緩衝
public function __construct(array $arr = []) {
$this->arr = $arr;
return is_array($arr);
}
// 獲取父級/子級/當前位置路徑陣列
public function get_parent($myid) { ... }
public function get_child($myid) { ... }
public function get_pos($myid, &$newarr) { ... }
// 核心:生成樹形 HTML 字串
public function get_tree($myid, $str, $sid = 0, $adds = '', $str_group = '') { ... }
// 多選版本
public function get_tree_multi($myid, $str, $sid = 0, $adds = '') { ... }
// 核心:返回格式化陣列
public function getArray($myid = 0, $sid = 0, $adds = '') { ... }
}
?>
數據格式範例
$data = [
1 => ['id'=>1, 'pid'=>0, 'title'=>'一級欄目一'],
2 => ['id'=>2, 'pid'=>0, 'title'=>'一級欄目二'],
3 => ['id'=>3, 'pid'=>1, 'title'=>'二級欄目一'],
4 => ['id'=>4, 'pid'=>1, 'title'=>'二級欄目二'],
5 => ['id'=>5, 'pid'=>2, 'title'=>'二級欄目三'],
6 => ['id'=>6, 'pid'=>3, 'title'=>'三級欄目一'],
7 => ['id'=>7, 'pid'=>3, 'title'=>'三級欄目二'],
];
使用範例
1. 生成下拉選單
<?php
$tree = new Tree($data);
$str = "<option value='\$id' \$selected>\$spacer \$title</option>";
echo "<select>" . $tree->get_tree(0, $str, $selected_id) . "</select>";
?>
2. 生成樹形菜單
<?php
$tree = new Tree($data);
$str = "<li>\$spacer <a href='?cid=\$id'\>\$title</a></li>";
echo "<ul>" . $tree->get_tree(0, $str) . "</ul>";
?>
3. 獲取格式化陣列(自行渲染)
<?php
$tree = new Tree($data);
$formatted = $tree->getArray(0);
// $formatted 每項包含 title(已含縮進符)、id、pid 等原始字段
foreach ($formatted as $item) {
echo $item['title'] . '
';
}
?>
關鍵方法解析
| 方法 | 用途 | 關鍵參數 |
| get_tree() | 單選下拉/樹形 HTML | $str 模板字串(變量用 \$var),$sid 選中 ID,$str_group 根節點模板 |
| get_tree_multi() | 多選下拉($sid 為逗號分隔字串) | 同上 |
| getArray() | 返回格式化陣列 | 無模板,直接可遍歷渲染 |
模板變量說明
\$id、\$pid、\$title:數據字段(需與陣列鍵名一致)。
\$spacer:層級縮進符號(由 $icon 組合)。
\$selected:若當前 ID==$sid 則為 'selected',否則空。
\$adds:遞歸傳遞的前綴符號串。
注意事項
- 使用
eval() 解析模板,**務必確保數據來源可信**,防止代碼注入。
- 大數據量(>萬級)遞歸可能超出記憶體/棧限制,建議改用非遞歸或分批處理。
- 字段名固定為
id/pid/title,若不同需修改類內部鍵名或預處理數據映射。