無限級分類是 CMS、電商後台的核心結構。本文以 ThinkPHP 3.x 為例,展示如何利用 path 欄位儲存祖先路徑、Model 回調自動維護 path、Controller 排序邏輯、View 利用 volist+for 縮進顯示層級,完整呈現從建表到增刪改查的閉環。
CREATE TABLE `xp_cate` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL DEFAULT '' COMMENT '分類名稱', `pid` int(11) NOT NULL DEFAULT '0' COMMENT '父級ID', `path` varchar(255) NOT NULL DEFAULT '' COMMENT '祖先路徑,如 0-1-3', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;

where("id=$pid")->find();
return $parent['path'] . '-' . $parent['id']; // 子分類繼承父 path + 父 id
}
}
}
field("id,name,pid,path,concat(path,'-',id) as bpath")
->order('bpath')->select();
// 計算層級數 (path 以 - 分割的段數)
foreach ($list as $key => $val) {
$list[$key]['level'] = count(explode('-', $val['bpath'])) - 1;
}
$this->assign('alist', $list);
$this->display();
}
// 新增
function add() {
$cate = D('Cate');
if ($vo = $cate->create()) {
if ($cate->add()) {
$this->success('新增成功');
} else {
$this->error('新增失敗');
}
} else {
$this->error($cate->getError());
}
}
}
<form action="/Article/add" method="post">
請選擇父級欄目:
<select name="pid" size="20">
<option value="0">根欄目</option>
<volist name="alist" id="vo">
<option value="{$vo.id}">
<for start="0" end="$vo.level"> </for>
{$vo.name}
</option>
</volist>
</select><br />
新的欄目名稱:<input type="text" name="name" /><br />
<input type="submit" value="添加欄目" />
</form>

path 儲存「祖先 ID 串」,如 0-1-3 表示頂級→1→3。path,拼接生成自身 path。concat(path,'-',id) as bpath 產生完整排序鍵,ORDER BY bpath 即得樹狀順序。explode('-', bpath) 的段數 - 1,View 用 for 迴圈輸出縮進空格。此方案無需遞迴查詢,單次 SQL 即可取得完整樹狀結構,效能極佳,適合萬級分類資料。