在開發程式的時候,有時候,我們需要擷取所有欄目(包括一級欄目、二級欄目、三級欄目等等),并按照父子關系形成樹型結構。可以采取使用遞歸或者通過引用方式(php中引用類似C或者C++中的指針,隻不過換一種說法而已)。
通過引用方式實作無限極分類
思路:
1.即所有待處理的資料進行包裝成下标為主鍵id( pk)的數組,便于有 pid擷取對應的父欄目。
2.對包裝的資料進行循環,如果為根節點,則将其引用添加到 tree中,否則,将其引用添加到其父類的子元素中。這樣雖然 tree中,隻是添加了根節點,但是每個根節點如果有子元素,其中包含了子元素的引用。故能形成樹型。
代碼如下
/**
* 把傳回的資料集轉換成Tree
* @param array $list 要轉換的資料集
* @param string $pk 自增字段(欄目id)
* @param string $pid parent标記字段
* @return array
* @author dqs <[email protected]>
*/
function make_tree($list,$pk='id',$pid='pid',$child='_child',$root=){
$tree=array();
$packData=array();
foreach ($list as $data) {
$packData[$data[$pk]] = $data;
}
foreach ($packData as $key =>$val){
if($val[$pk]==$root){//代表跟節點
$tree[]=& $packData[$key];
}else{
//找到其父類
$packData[$val[$pid]][$child][]=& $packData[$key];
}
}
return $tree;
}
資料結構如下:

執行結果如下
Array
(
[] => Array
(
[id] =>
[pid] =>
[title] => 測試
[url] => test1
[sort] =>
[create_time] =>
[update_time] =>
[status] =>
[target] =>
)
[] => Array
(
[id] =>
[pid] =>
[title] => 測試
[url] => test2
[sort] =>
[create_time] =>
[update_time] =>
[status] =>
[target] =>
)
[] => Array
(
[id] =>
[pid] =>
[title] => 首頁
[url] => Index/index
[sort] =>
[create_time] =>
[update_time] =>
[status] =>
[target] =>
)
[] => Array
(
[id] =>
[pid] =>
[title] => 部落格
[url] => Article/index?category=blog
[sort] =>
[create_time] =>
[update_time] =>
[status] =>
[target] =>
[_child] => Array
(
[] => Array
(
[id] =>
[pid] =>
[title] => 個人部落格
[url] => ownblog
[sort] =>
[create_time] =>
[update_time] =>
[status] =>
[target] =>
[_child] => Array
(
[] => Array
(
[id] =>
[pid] =>
[title] => 新浪部落格
[url] => sinaBlog
[sort] =>
[create_time] =>
[update_time] =>
[status] =>
[target] =>
)
)
)
[] => Array
(
[id] =>
[pid] =>
[title] => 他人部落格
[url] => otherBlog
[sort] =>
[create_time] =>
[update_time] =>
[status] =>
[target] =>
)
)
)
[] => Array
(
[id] =>
[pid] =>
[title] => 官網
[url] => http://www.onethink.cn
[sort] =>
[create_time] =>
[update_time] =>
[status] =>
[target] =>
)
)
附加OneThink中無限極分類函數
/**
* 把傳回的資料集轉換成Tree
* @param array $list 要轉換的資料集
* @param string $pid parent标記字段
* @param string $level level标記字段
* @return array
* @author 麥當苗兒 <[email protected]>
*/
function list_to_tree($list, $pk='id', $pid = 'pid', $child = '_child', $root = ) {
// 建立Tree
$tree = array();
if(is_array($list)) {
// 建立基于主鍵的數組引用
$refer = array();
foreach ($list as $key => $data) {
$refer[$data[$pk]] =& $list[$key];
}
foreach ($list as $key => $data) {
// 判斷是否存在parent
$parentId = $data[$pid];
if ($root == $parentId) {
$tree[] =& $list[$key];
}else{
if (isset($refer[$parentId])) {
$parent =& $refer[$parentId];
$parent[$child][] =& $list[$key];
}
}
}
}
return $tree;
}
通過遞歸方式實作無限極分類
思路:
1.使用循環,分别擷取所有的根節點。
2.在擷取每個節點的時候,将該節點從原資料中移除,并遞歸方式擷取其所有的子節點,一直原資料為空。
代碼實作如下:
function make_tree1($list,$pk='id',$pid='pid',$child='_child',$root=){
$tree=array();
foreach($list as $key=> $val){
if($val[$pid]==$root){
//擷取目前$pid所有子類
unset($list[$key]);
if(! empty($list)){
$child=make_tree1($list,$pk,$pid,$child,$val[$pk]);
if(!empty($child)){
$val['_child']=$child;
}
}
$tree[]=$val;
}
}
return $tree;
}
效果截圖如下: