Re: [請益] PHP怎麼寫樹狀清單

看板PHP作者 (寶貝豬)時間16年前 (2009/12/04 09:29), 編輯推噓2(203)
留言5則, 3人參與, 最新討論串4/4 (看更多)
※ 引述《wallsem (小樂)》之銘言: : 最近想用php寫樹狀清單 : 想問一下~要怎麼寫?! : 我要資料庫新增,目錄或子目錄就會增加... : 一定要用迴圈才可以嗎~~ : 有沒有其他的方法!! 先把規格開出來, 包括樹狀結構的資料表規劃, 例如: 資料表 - 選單項目: tree_items: id, name, parent_id, note id: 選單項目的主鍵 name: 選單項目的名稱 parent_id: 父層的id note: 關於這個選單項目的描述 存取選單項目資料表的函式: 1 新增一項選單項目 function tree_items_add(name,parent_id,note) 2 從資料庫中取出整個[選單項目集], function &db2items() 3 將[選單項目集]所有記錄的 id 及其 parent_id 的關聯 轉成[php array tree]的結構, function &items2tree($items) 4 製作[php array tree]的view, 例如以樹狀表達形式呈現在網頁上. function tree2view($tree,&$items) 上述 1 的實作省略, 就是利用sql的insert語法插入資料而已. 如果是第一 個節點(根節點), 則其 parent_id 設為 0. 補充說明一下: 為了跟以下的架構相呼應, 一個tree的根節點只能有一個, 意即tree_items裏 parent_id 為 0 的記錄只能有一筆. 除了新增以外, 其它資料管理功能還有檢視, 修改, 刪除, 查詢等就依實際 需求自訂. 至於 2, 3, 4 需要提一下. 網路上應該找得出現成的code, 可能php的官網 的範例就有. 不過自己刻當做是練功也可(一開始可能得花不少時間試誤). php array tree的結構是這樣子的: $tree = array( '1' => array( '2' => array( '3' => array( '4' => array() ) ), '5' => array( '6' => array(), '7' => array() ) ) ); 樹狀表達形式 - text形式: 1 2 3 4 5 6 7 假設選單項目的資料都建好了, 接著要呈現在網頁上的程式架構大致上是: <?php //載入系統組態檔, 在此主要是定義資料庫連線物件變數, 需要自備: include 'configure.inc.php'; //從資料庫中取出整個[選單項目集], $items = db2items(); //將[選單項目集]所有記錄的 id 及其 parent_id 的關聯 //轉成[php array tree]的結構, $tree = items2tree($items); //製作[php array tree]的view, 例如以樹狀表達形式呈現在網頁上. $html = tree2view($tree,$items); echo $html; ?> 接著以下是程式碼, 是從既有已驗證過可執行的函式庫抓出來的. 但在這篇文章 中為了需要稍有改一些細項, 未經實際測試, 不確定是否能run得起來, 僅供參考. <?php //從資料庫中取出整個[選單項目集] function &db2items(){ //資料庫連線的物件變數, 假設在系統組態檔裏已完成初始化. //這裏直接以global方式引用. 不然在本函式內自訂亦可. global $DB_link; //先把 tree_items 全部抓出來 $sql = "select * from tree_items"; $rows = mysql_query($sql,$DB_link); $items=array(); while ( $row = mysql_fetch_assoc($rows) ){ $items[$row['id']]=$row; } return $items; } //將[選單項目集]記錄轉成[php array tree]的結構 function &items2tree($items){ //再把 $items 當中所有item的 id及parent_id 轉成 php array tree $tree=array(); //$reftab用來記錄item在tree裏位置的reference. $reftab=array(); foreach($items as $key => $row) { $pkey=$row['parent_id']; if($pkey==0) { //代表這是根節點 $tree[$key]=array(); $reftab[$key]=&$tree[$key]; } else { //代表這是一般節點 if(!isset($reftab[$pkey])){ $reftab[$pkey]=array(); } if(!isset($reftab[$key])){ $reftab[$key]=array(); } $reftab[$pkey][$key]=&$reftab[$key]; } return $tree; } //製作[php array tree]的view, 例如以樹狀表達形式呈現在網頁上 //這裏僅以簡單的文字形式表示. 若有實際應用上的需求, 亦可自訂 //套用 html, 或是 javascript等樣板來達到目的. function tree2view($tree,&$items){ $text=''; _php2text($text,$tree,0,$items); return $text; } //以遞迴方式呈現php array tree //$Depth代表樹狀結構的深度, 0代表根層. 輸出結果以空格代表層數. function _php2text(&$text,$tree,$Depth,&$items) { if(!$tree) return; foreach($tree as $k=>$v) { $blanks=''; for($i=0;$i<$Depth;$i++) $blanks.=' '; $text.=$blanks.$items[$k]['name']."\r\n"; //遞迴呼叫: _php2text($text,$v,$Depth+1,$items); } } ?> ※ 編輯: bobju 來自: 58.115.151.184 (12/04 09:41)

12/04 10:19, , 1F
關於樹狀資料結構的資料表設計,進階的有MPTT,google找就有.
12/04 10:19, 1F

12/04 10:19, , 2F
不過要弄懂MPTT得有些資料結構跟演算法的基礎,否則看嘸.
12/04 10:19, 2F

12/04 10:20, , 3F
MPTT: Modified Preorder Tree Traversal
12/04 10:20, 3F
※ 編輯: bobju 來自: 58.115.151.184 (12/04 11:44)

12/07 18:26, , 4F
http://0rz.tw/TRFow 我之前有看過這個
12/07 18:26, 4F

12/11 11:49, , 5F
12/11 11:49, 5F
文章代碼(AID): #1B66Np8v (PHP)
文章代碼(AID): #1B66Np8v (PHP)