//////////////////////***树形结构***/////////////////////////////
/**
* 递归生成树形结构
* @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;
}