無限極分類.html
本文部落格部分內容是上述網上內容搬運過來的。
無限極分類在web**中應用很多,比如無限極選單,無限極資料夾展開。因為最近的專案中有用到樹的結構,其實就是無限極選單的儲存。
在某次面試中也有提及,所以這裡集合上述網上的資料總結一下。
使用場景:
1、需要獲取所有的節點,也就是無限極選單的樹形結構分類。
2、獲取某個節點的所有葉子節點。
3、獲取某個節點的所有子孫節點。
4、非葉子節點的分頁展示。
無限極分類其實就是一棵樹,所有的節點作為乙個儲存元素。每個節點可以有任意個孩子節點,且只有乙個父節點。
mysql資料儲存,結合專案的資料表儲存結構如下:
create table t_tree_info (
`fid` bigint(20) unsigned not null auto_increment comment '標籤自增id',
`fname` varchar(255) not null default '' comment '節點名稱',
`fpid` bigint(20) unsigned not null default 0 comment '父節點id',
`fadd_time` timestamp not null default '0000-00-00 00:00:00' comment '建立時間',
`fmodify_time` timestamp not null default current_timestamp on update current_timestamp comment '修改時間',
primary key (`fid`)
) engine=innodb default charset=utf8 comment='無限極分類選單儲存表';
核心字段就是節點自身唯一標識fid
,和對應的父節點標識fpid
。
節點資料在專案中是mysql儲存的,現在為了測試,把mysql資料直接存放到陣列裡面,全域性使用。資料儲存如下:
private static $listdata = [
[ "fid" => 1,
"fpid" => 8,
"fname" => '首頁',
],[ "fid" => 2,
"fpid" => 8,
"fname" => '部落格',
],[ "fid" => 3,
"fpid" => 8,
"fname" => '官網',
],[ "fid" => 4,
"fpid" => 2,
"fname" => '個人部落格',
],[ "fid" => 5,
"fpid" => 2,
"fname" => '他人部落格',
],[ "fid" => 6,
"fpid" => 8,
"fname" => '測試1',
],[ "fid" => 7,
"fpid" => 8,
"fname" => '測試2',
],[ "fid" => 8,
"fpid" => 0,
"fname" => '無限極分類',
],[ "fid" => 9,
"fpid" => 5,
"fname" => '女性欄目',
],[ "fid" => 10,
"fpid" => 5,
"fname" => '男性欄目',
],];
思路:
1、即所有待處理的資料進行包裝成下標為主鍵fid(pk)的陣列,便於由fpid獲取對應的父欄目。
2、對包裝的資料進行迴圈,如果為根節點,則將其引用新增到tree中,否則,將其引用新增到其父類的子元素中。這樣雖然tree中,只是新增了根節點,但是每個根節點如果有子元素,其中包含了子元素的引用。故能形成樹型。
個人覺得引用的設計思路相比遞迴的思路更容易理解,更直觀一些。
**如下:
/**
* 把返回的資料集轉換成tree
* @param array $list 要轉換的資料集
* @param string $pk 自增字段(欄目fid)
* @param string $pid parent標記字段
* @return array
*/public static function quote_make_tree($list, $pk = 'fid', $pid = 'fpid',$child = '_child', $root = 0)
foreach ($packdata as $key =>$val) else
} return $tree;
}
引用呼叫樹:
/**
* 引用生成樹
* @return
*/public static function quote_tree_test()
返回結果如下:
[,,
,]}]
},,,]
}]
思路:
1、使用迴圈,分別獲取所有的根節點。
2、在獲取每個節點的時候,將該節點從原資料中移除,並遞迴方式獲取其所有的子節點,一直原資料為空。
**如下:
/**
* 遞迴生成樹
* @param array $list 要轉換的資料集
* @param string $pk 自增字段(欄目id)
* @param string $pid parent標記字段
* @param string $child 孩子節點key
* @param integer $root 根節點標識
* @return array
*/public static function recursive_make_tree($list, $pk = 'fid', $pid = 'fpid', $child = '_child', $root = 0)
}$tree = $val;
}} return $tree;
}
遞迴呼叫樹:
public static function recursive_tree_test()
思路:
1、如果當前節點不是某個節點的父節點,則說明當前節點是葉子節點。則返回當前節點。同時也是遞迴出口。
2、如果當前節點是某個節點的父節點,則說明當前節點不是葉子節點。針對當前節點的孩子節點進行同樣遞迴查詢。
**如下:
/**
* 獲取某節點的所有葉子節點
* 如果當前節點是葉子節點,則返回本身
* @param $pid
* @return array
*/public static function getallleafnodebyfatherids($pid )
";$res = $this->db->fetchrow($sql);
if ($res && $res['fid'])
}return $allleaftagids;
} else
}
思路:
1、如果當前節點不是某個節點的父節點,說明當前節點是葉子節點,則返回空。同時也是遞迴出口。
2、如果當前節點是某個節點的父節點,則合併當前節點到返回陣列中;然後對該節點的所有孩子節點進行同樣的遞迴查詢。
**如下:
/**
* 根據父節點獲取所有的子節點
* @param $pids
* @return array
*/public static function getallchildnodebyfatherids($pids)
$allchildtagids = ;
$tagidsstr = implode(',', array_unique($pids));
$sql = "select group_concat(fid) as fid from t_tree_info where fpid in()";
$res = $this->db->fetchrow($sql);
if ($res && $res['fid']) else
}
思路:
1、獲取非葉子節點,只要節點不是其他節點的父節點即可。
**如下:
# mysql分頁查詢語句
select sql_calc_found_rows fid, fname, fpid, fadd_time, fmodify_time from t_tree_info where fid in(select distinct fpid from t_tree_info) order by fadd_time desc limit 0, 10
php無限極分類
無限級分類 param1 array categories,要分類的陣列 param2 int stop id 不需要查詢子分類的id param3 int parent id 0,要查詢父分類id 欄位名稱 param4 int level 0,當前商品分類所屬的層級 根據level計算縮排的距離...
PHP無限極分類
function gentree5 items function gentree7 items items array 1 array id 1,pid 0,name 江西省 2 array id 2,pid 0,name 黑龍江省 3 array id 3,pid 1,name 南昌市 4 arr...
php無限極分類
這裡首先介紹一下,什麼是無限極分類?無限極分類簡單點說就是乙個類可以分成多個子類,然後乙個子類又可以分另外多個子類這樣無限分下去,就好象windows可以新建乙個資料夾,然後在這個資料夾裡又可以建一些個資料夾,在資料夾底下還可以建一些資料夾一樣 那php又是如何實現它的無限分類的呢?如何把它的各個分...