# 分层数据 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;
}``````

《L03 构架 API 服务器》

《L02 从零构建论坛系统》

3年前 评论

3年前 评论

3年前 评论

20

55

168

229