php无限极分类(递归+引用)、生成(树形/层级)结构、拼接结构(option选项)、数组递归/递归查询


//////////////////////***树形结构***/////////////////////////////

/**
 * 递归生成树形结构
 * @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('&emsp;&emsp;',$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('&emsp;&emsp;',$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('&emsp;&emsp;',$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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章