需要實現的效果:
資料表結構:
代碼:
#### 檔案夾操作 ## 檔案夾類 class Folder{ public $id; public $parent_id; public $name; public $children = array(); function __construct($id,$parent_id,$name){ $this->id = $id; $this->parent_id = $parent_id; $this->name = $name; } } ## 資料夾樹狀目錄 function folder_tree(){ global $domain_id; global $mailbox_id; $folder_arr = mysql::select("select id,parent_id,name from wm_netdisk_folder where domain_id=$domain_id and mailbox_id=$mailbox_id"); $folders = array(); # 轉換為Folder實體 foreach($folder_arr as $key=>$value){ $id = $value['id']; $parent_id = $value['parent_id']; $name = $value['name']; $folders[] = new Folder($id,$parent_id,$name); } # 頂級folder id $top_id = 0; # tree的第一層資料 $top = array(); # 其他資料 $table = array(); foreach($folders as $key=>$value){ if($value->parent_id==$top_id){ $top[] = $value; }else{ $table[] = $value; } } tree_help($top,$table); return $top; } ## folder_tree輔助函數(遞迴) function tree_help(&$top,&$table){ foreach($top as $a=>$b){ $id = $b->id; foreach($table as $c=>$d){ $parent_id = $d->parent_id; if($id==$parent_id){ $b->children[] = $d; $record[] = $parent_id; } } tree_help($b->children,$table); } } ## 將folder_tree格式化為option html片段(遞迴) $chrs = array('│','├','└',' '); function to_html($datas,$base_line,&$rs){ global $chrs; $len = count($datas); $count = 0; foreach($datas as $key=>$value){ $count++; # 層級分割串 $line = ''; if($count == $len){ $line = $base_line.$chrs[2]; }else{ $line = $base_line.$chrs[1]; } $id = $value->id; $name = $value->name; $pid = $value->parent_id; $option = "<option value='$id' data-pid='$pid'>$line$name</option>"; $rs[] = $option; if(count($value->children)>0){ if($count == $len){ $line = $base_line.$chrs[3]; }else{ $line = $base_line.$chrs[0]; } to_html($value->children,$line,$rs); } } }
思路:
1. 首先從資料表中取得所有檔案夾資訊。
2. 分組頂層(parent_id=0) as $top和其他資料 as $table。
3. 遍曆$top,在$table中找parent_id=$top->id的項,加入到$top->children中,然後對$top->children進行相同的遞迴,直到把$table中所有資料進行分類。
4. 3中得到的資料結構大概是:[{"id":x,"name":y,"children":[...]}]
5 .把3中得到的資料格式化為所需要的html片段。
和python,javascript不同,php數組在函數間傳遞時候傳遞的是副本,如果需要保持引用,就在形參上前加&。