分层数据Hierarchical Data探索(1.递归)

分层数据Hierarchical Data探索（例如：无限级分类、多级菜单、省份城市）

引言

)方法来实现无限极分类，然后再通过 两种数据模型

三种方式的变量传递

• & 引用赋值
function doloop1(&$i = 1) { print_r($i);
$i++; if ($i <= 10) {
doloop1($i); } } doloop1(); • static 静态变量 function doloop2() { static$i = 1;
print_r($i);$i++;
if ($i <= 10) { doloop2(); } } doloop2(); • global 全局变量 $i = 1;
function doloop3()
{
global $i; echo$i;
$i++; if ($i <= 10) {
doloop3();
}
}
doloop3();

构建模拟数据

# 模拟数据
$data = [ ['id' => 1, 'title' => 'Electronics', 'parent_id' => 0], ['id' => 2, 'title' => 'Laptops & PC', 'parent_id' => 1], ['id' => 3, 'title' => 'Laptops', 'parent_id' => 2], ['id' => 4, 'title' => 'PC', 'parent_id' => 2], ['id' => 5, 'title' => 'Cameras & photo', 'parent_id' => 1], ['id' => 6, 'title' => 'Camera', 'parent_id' => 5], ['id' => 7, 'title' => 'Phones & Accessories', 'parent_id' => 1], ['id' => 8, 'title' => 'Smartphones', 'parent_id' => 7], ['id' => 9, 'title' => 'Android', 'parent_id' => 8], ['id' => 10, 'title' => 'iOS', 'parent_id' => 8], ['id' => 11, 'title' => 'Other Smartphones', 'parent_id' => 8], ['id' => 12, 'title' => 'Batteries', 'parent_id' => 7], ['id' => 13, 'title' => 'Headsets', 'parent_id' => 7], ['id' => 14, 'title' => 'Screen Protectors', 'parent_id' => 7], ]; 获取无限极分类 /** * 值引用获取无限极分类树 * * @param array$data
* @return array
*/
function make_tree($data) {$refer = array();
$tree = array(); foreach($data as $k =>$v){
$refer[$v['id']] = & $data[$k];  //创建主键的数组引用
}

foreach($data as$k => $v){$parent_id = $v['parent_id']; //获取当前分类的父级id if($parent_id == 0){
$tree[] = &$data[$k]; //顶级栏目 }else{ if(isset($refer[$parent_id])){$refer[$parent_id]['children'][] = &$data[$k]; //如果存在父级栏目，则添加进父级栏目的子栏目数组中 } } } return$tree;
}

/**
* 递归获取无限极分类树
*
* @param array $data * @param int$parent_id
* @param int $level * @return array */ function make_tree2($data = [], $parent_id = 0,$level = 0)
{
$tree = []; if ($data && is_array($data)) { foreach ($data as $v) { if ($v['parent_id'] == $parent_id) {$tree[] = [
'id' => $v['id'], 'level' =>$level,
'title' => $v['title'], 'parent_id' =>$v['parent_id'],
'children' => make_tree2($data,$v['id'], $level + 1), ]; } } } return$tree;
}

获取子节点以及节点的层级

/**
* 引用赋值方式
* @param array $data * @param int$id
* @param int $level * @return array */ function getSubTree($data = [], $id = 0,$level = 0)
{
static $tree = []; foreach ($data as $key =>$value) {
if ($value['parent_id'] ==$id) {
$value['laravel'] =$level;
$tree[] =$value;
getSubTree($data,$value['id'], $level + 1); } } return$tree;
}

/**
* 静态变量方式
* @param array $data * @param int$id
* @param int $level * @return array */ function getSubTree($data = [], $id = 0,$level = 0)
{
static $tree = []; foreach ($data as $key =>$value) {
if ($value['parent_id'] ==$id) {
$value['laravel'] =$level;
$tree[] =$value;
getSubTree($data,$value['id'], $level + 1); } } return$tree;
}

/**
* 全局变量方式
* @param array $data * @param int$id
* @param int $level * @return array */$tree = [];  //先申明变量
function getSubTree($data = [],$id = 0, $level = 0) { global$tree;

foreach ($data as$key => $value) { if ($value['parent_id'] == $id) {$value['laravel'] = $level;$tree[] = $value; getSubTree($data, $value['id'],$level + 1);
}
}
return $tree; } 通过pid获取所有上级分类 常用于面包屑导航 /** * getParentsByParentId2($categories, 9)
*
* @param array $data * @param$parent_id
* @return array
*/
function getParentsByParentId($data = [],$parent_id)
{
static $categories = []; if ($data && is_array($data)) { foreach ($data as $item) { if ($item['id'] == $parent_id) {$categories[] = $item; getParentsByParentId($data, $item['parent_id']); } } } return$categories;
}

function getParentsByParentId2($data = [],$parent_id)
{
$categories = []; if ($data && is_array($data)) { foreach ($data as $item) { if ($item['id'] == $parent_id) {$categories[] = $item;$categories = array_merge($categories, getParentsByParentId2($data, $item['parent_id'])); } } } return$categories;
}