//////////////////////***樹形結構***/////////////////////////////
/**
* 遞歸生成樹形結構
* @param array $array 所有分類數據
* @param int $pid 父級id
* @return array
*/
function getTrees($array,$pid = 0){
$tree = array();
foreach ($array as $key => $value) {
if ($value['pid'] == $pid) {
unset($array[$key]);/* 銷燬節點,減少後續遞歸消耗 */
$child = getTrees($array, $value['id']);
if (!empty($child)){
$value['child'] = $child;
}
$tree[] = $value;
}
}
return $tree;
}
//////////////////////***層級結構***/////////////////////////////
/**
* 遞歸生成層級結構
* @param array $array 所有分類數據
* @param int $pid 父級id
* @param int $level 層級
* @return mixed
*/
function getChilds($array,$pid = 0,$level = 0){
static $res;//聲明靜態數組,用於保存數據
foreach ($array as $key => $value){
//第一次找到根節點 也就是pid=0的節點
if($value['pid'] == $pid){
$value['level'] = $level;
$res[] = $value;
unset($array[$key]);/* 銷燬節點,減少後續遞歸消耗 */
//遞歸查找父ID爲該節點id的節點,層級則爲原級別+1
getChilds($array,$value['id'],$level+1);
}
}
return $res;
}
/**
* (遞歸和引用)生成層級結構
* @param array $array 所有分類數據
* @param int $pid 父級id
* @param int $level 層級
* @param array $res 保存數據
* @return array
*/
function getChildsCite($array,$pid = 0,$level = 0,&$res = array()){
foreach ($array as $key => $value) {
if ($value['pid'] == $pid) {
$value['level'] = $level;
$res[] = $value;
unset($array[$key]);/* 銷燬節點,減少後續遞歸消耗 */
getChildsCite($array, $value['id'],$level+1,$res);
}
}
return $res;
}
/* 和靜態變量使用方式一樣,感覺靜態變量方式比較好 */
//////////////////////***拼接結構***/////////////////////////////
/**
* 遞歸形式生成拼接結構
* @param array $array 所有分類數據
* @param int $pid 父級id
* @param int $selval 選中的id (編輯時一般爲父級id)
* @param int $current 當前編輯的id(用於編輯分類時不顯示自己的id)
* @param int $level 層級
* @return string
*/
function getTreesSplice($array,$pid = 0,$selval = 0,$current = 0,$level = 0){
$str = '';
foreach ($array as $key => $value) {
if ($value['pid'] == $pid) {
unset($array[$key]);/* 銷燬節點,減少後續遞歸消耗 */
$levelstr = str_repeat('  ',$level);
$selected = ($selval == $value['id']) ? 'selected' : '';
if ($current != $value['id']){
$str .= '<option '.$selected.' value="'.$value['id'].'">'.$levelstr.$value['name'].'</option>';
}
$str .= getTreesSplice($array, $value['id'],$selval,$current,$level+1);
}
}
return $str;
}
/**
* 遞歸形式(頭部插入父級選項)生成拼接結構
* @param array $array 所有分類數據
* @param int $pid 父級id
* @param int $selval 選中的id (編輯時一般爲父級id)
* @param int $current 當前編輯的id(用於編輯分類時不顯示自己的id)
* @param int $level 層級
* @param bool $topstr 是否插入父級選項
* @return string
*/
function getTreesSpliceTopStr($array,$pid = 0,$selval = 0,$current = 0,$level = 0,$topstr = false){
$str = '';
foreach ($array as $key => $value) {
if ($topstr && $value['id'] == $pid){
$str = substr_replace($str,'<option value="'.$value['id'].'" >'.$value['name'].'</option>',0,0);
}
if ($value['pid'] == $pid) {
unset($array[$key]);/* 銷燬節點,減少後續遞歸消耗 */
$levelstr = str_repeat('  ',$level);
$selected = ($selval == $value['id']) ? 'selected' : '';
if ($current != $value['id']){
$str .= '<option '.$selected.' value="'.$value['id'].'">'.$levelstr.$value['name'].'</option>';
}
$str .= getTreesSplice($array, $value['id'],$selval,$current,$level+1);
}
}
return $str;
}
/**
* (遞歸+靜態變量形式)生成拼接結構
* @param array $array 所有分類數據
* @param int $pid 父級id
* @param int $selval 選中的id (編輯時一般爲父級id)
* @param int $current 當前編輯的id(用於編輯分類時不顯示自己的id)
* @param int $level 層級
* @return string
*/
function getChildsSplice($array,$pid = 0,$selval = 0,$current = 0,$level = 0){
static $str;//聲明靜態變量,用於保存數據
foreach ($array as $key => $value){
//第一次找到根節點 也就是pid=0的節點
if($value['pid'] == $pid){
$levelstr = str_repeat('  ',$level);
$selected = ($selval == $value['id']) ? 'selected' : '';
if ($current != $value['id']){
$str .= '<option '.$selected.' value="'.$value['id'].'">'.$levelstr.$value['name'].'</option>';
}
unset($array[$key]);/* 銷燬節點,減少後續遞歸消耗 */
//遞歸查找父ID爲該節點id的節點,層級則爲原級別+1
getChildsSplice($array,$value['id'],$selval,$current,$level+1);
}
}
return $str;
}
/**
* 遞歸查表形式生成拼接結構
* @param int $pid 父級id
* @param int $selval 選中的id (編輯時一般爲父級id)
* @param int $current 當前編輯的id(用於編輯分類時不顯示自己的id)
* @param int $level 層級
* @return string
*/
function GetCategoriesSplice($pid = 0,$selval = 0,$current = 0,$level = 0){
/* 查詢父級下的數據 */
$array=\think\Db::table('categories')->where('parent',$pid)->select();
$str = '';
foreach($array as $key => $value) {
if($value['parent'] == $pid) {
$levelstr = str_repeat('  ',$level);
$selected = ($selval == $value['id']) ? 'selected' : '';
if ($current != $value['id']){
$str .= '<option '.$selected.' value="'.$value['id'].'">'.$levelstr.$value['name'].'</option>';
}
$str .= GetCategoriesSplice($value['id'],$selval,$current,$level+1);/* 遞歸查詢 */
}
}
return $str;
}
////***調用***////
//需要遞歸的數組
$arr = array(
array('id'=>1,'name'=>'名稱1','pid'=>0),
array('id'=>2,'name'=>'名稱2','pid'=>0),
array('id'=>3,'name'=>'名稱3','pid'=>0),
array('id'=>4,'name'=>'名稱4','pid'=>0),
array('id'=>5,'name'=>'名稱5','pid'=>0),
array('id'=>6,'name'=>'名稱1-1','pid'=>1),
array('id'=>7,'name'=>'名稱1-2','pid'=>1),
array('id'=>8,'name'=>'名稱2-1','pid'=>2),
array('id'=>9,'name'=>'名稱2-2','pid'=>2),
array('id'=>10,'name'=>'名稱3-1','pid'=>3),
array('id'=>11,'name'=>'名稱1-1-1','pid'=>6),
array('id'=>12,'name'=>'名稱1-1-2','pid'=>6),
array('id'=>13,'name'=>'名稱1-2-1','pid'=>7),
array('id'=>14,'name'=>'名稱2-1-1','pid'=>8),
array('id'=>15,'name'=>'名稱2-1-2','pid'=>8),
array('id'=>16,'name'=>'名稱2-2-1','pid'=>9),
array('id'=>17,'name'=>'名稱2-1-1-1','pid'=>14),
array('id'=>18,'name'=>'名稱2-1-2-1','pid'=>15),
array('id'=>19,'name'=>'名稱2-1-1-1-1','pid'=>17),
array('id'=>20,'name'=>'名稱3-1-1','pid'=>10),
);
//$trees = getTrees($arr);
//print_r($trees);
//$childs = getChilds($arr);
//print_r($childs);
//$childscite = getChildsCite($arr);
//print_r($childscite);
//echo '<select>';
//$treessplicestr = getTreesSplice($arr,0,6,11);
//print_r($treessplicestr);
//echo '</select>';
//echo '<select>';
//$treessplicetopstr = getTreesSpliceTopStr($arr,2,0,0,1,true);
//print_r($treessplicetopstr);
//echo '</select>';
//echo '<select>';
//$getcategoriessplice = GetCategoriesSplice();
//print_r($getcategoriessplice);
//echo '</select>';die;
以下是參考文檔:一次循環(引用生成樹形)
/**
* 核心函數, 將列表數據轉化樹形結構
* 使用前提必須是先有父後有子, 即兒子的id必須小於父親id
* 列表數據必須安裝id從小到大排序
* @param array $lists 原始列表數據
* @param string $childKey 字段名
* @return array 返回樹形數據
*/
function listToTree($lists, $childKey = 'children'){
$map = [];
$res = [];
foreach($lists as $id => &$item){
// 獲取出每一條數據的父id
$pid = &$item['pid'];
// 將每一個item的引用保存到$map中
$map[$item['id']] = &$item;
// 如果在map中沒有設置過他的pid, 說明是根節點, pid爲0,
if(!isset($map[$pid])){
// 將pid爲0的item的引用保存到$res中
$res[$id] = &$item;
}else{
// 如果在map中沒有設置過他的pid, 則將該item加入到他父親的葉子節點中
$pItem = &$map[$pid];
$pItem[$childKey][] = &$item;
}
}
return $res;
}