博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Php无限层级并显示层级数
阅读量:4577 次
发布时间:2019-06-08

本文共 3988 字,大约阅读时间需要 13 分钟。

今天在处理递归无限层级菜单时,遇到一个稍微烧脑的问题,如何显示当前节点所在的层级数。

废话不多说,我们先看个直观的无限层级:

1, 'name' => '一级菜单a', 'pid' => 0),// pid 父级id array('id' => 2, 'name' => '一级菜单b', 'pid' => 0), array('id' => 3, 'name' => '二级菜单a', 'pid' => 1), array('id' => 4, 'name' => '二级菜单b', 'pid' => 1), array('id' => 5, 'name' => '二级菜单c', 'pid' => 2), array('id' => 6, 'name' => '二级菜单d', 'pid' => 2), array('id' => 7, 'name' => '三级菜单a', 'pid' => 3), array('id' => 8, 'name' => '三级菜单b', 'pid' => 3), array('id' => 9, 'name' => '四级菜单a', 'pid' => 8),);/** 获取所有子节点 * @param $data 所有节点数组 * @param $id $pid 父级节点id * @param $level 层级 * @return array */function getTree($data, $pid, $level = 0){ $list = array(); foreach ($data as $k => $v) { if ($v['pid'] == $pid) { $v['level'] = $level; $v['name'] = $v['name'].'('.($level+1).'级)'; // 这里可以加个层级次数 $v['children'] = getTree($data, $v['id'], $level + 1); if ($v['children'] == null){ unset($v['children']); } $list[] = $v; } } return $list;}$menu = getTree($arr, 0, 0);$json = json_encode($menu);?>
Document

我们看到所有节点层级数没问题,那么我如何查看节点中pid=3的所有节点层级关系呢

$menu = getTree($arr, 3, 0);

显然不对,况且菜单展示并不友好,pid=3的父节点至少要显示在顶层吧。层级数暂且不管,我们先解决如何显示顶层pid=3的树形结构:

pid=3对应的节点是:二级菜单a。这个可以直接根据数据id查询出来,此处仅做演示哈。调整下代码:

$menu = getTree($arr, 3, 0);$menu = array(['name' => '二级菜单a','children'=> $menu]);$json = json_encode($menu);

OK,完美,同样要显示所有pid=1的节点层级关系,一样,pid=1对应的节点是 一级菜单a

$menu = getTree($arr, 1, 0);$menu = array(['name' => '一级菜单a','children'=> $menu]);$json = json_encode($menu);

好,回到 刚才的话题,如何正确的显示每个节点所在的层级数呢? 这里我也思考了很久,也没找到快捷的方法。

最终我还是递归的查询本节点所有的父节点id集合:完整代码如下:

1, 'name' => '一级菜单a', 'pid' => 0),// pid 父级id array('id' => 2, 'name' => '一级菜单b', 'pid' => 0), array('id' => 3, 'name' => '二级菜单a', 'pid' => 1), array('id' => 4, 'name' => '二级菜单b', 'pid' => 1), array('id' => 5, 'name' => '二级菜单c', 'pid' => 2), array('id' => 6, 'name' => '二级菜单d', 'pid' => 2), array('id' => 7, 'name' => '三级菜单a', 'pid' => 3), array('id' => 8, 'name' => '三级菜单b', 'pid' => 3), array('id' => 9, 'name' => '四级菜单a', 'pid' => 8),);/** 获取所有子节点 * @param $data 所有节点数组 * @param $id $pid 父级节点id * @param $level 层级 * @return array */function getTree($data, $pid, $level = 0){ $list = array(); foreach ($data as $k => $v) { if ($v['pid'] == $pid) { $v['level'] = $level; $v['name'] = $v['name'] . '(' . ($level + 1) . '级)'; // 这里可以加个层级次数 $v['children'] = getTree($data, $v['id'], $level + 1); if ($v['children'] == null) { unset($v['children']); } $list[] = $v; } } return $list;}/** 根据子节点获取父节点id * @param $data 所有节点数组 * @param $id id 主键id * @return array */function getParentid($data, $id){ $arr = array(); foreach ($data as $v) { if ($v['id'] == $id) { $arr[] = $v; //$arr[$v['id']]=$v['name']; $arr = array_merge(getParentid($data, $v['pid']), $arr); } } return $arr;}$id = 8 ; // 对应的节点是: 三级菜单b 对应的pid 是 3$pid = 3; // 对应的节点是 二级菜单a$toparr = getParentid($arr, $id); // 节点为8的所有父节点 id: 1 3 8 这里包含了自身,注意剔除$level = count($toparr); // 节点所在的层级数$menu = getTree($arr, $pid, $level-1);if($pid) $menu = array(['name' => '二级菜单a' . '(' . ($level-1) . '级)', 'children' => $menu]);$json = json_encode($menu);?>
Document

同样要显示所有节点:直接把pid赋值0,比如:

$id = 2 ; // 对应的节点是: 一级菜单b 对应的pid 是 0$pid = 0; // 对应的节点是 0 为 一级节点  显示所有节点,上面的$id用不到$toparr = getParentid($arr, $id); //$level = count($toparr); // 节点所在的层级数$menu = getTree($arr, $pid, $level-1);if($pid)    $menu = array(['name' => '二级菜单a' . '(' . ($level-1) . '级)', 'children' => $menu]);$json = json_encode($menu);

 看起来没毛病,博友们如果有好的办法获取任意一个节点所处的层级数,欢迎拍砖留言哈。

转载于:https://www.cnblogs.com/phpper/p/10821203.html

你可能感兴趣的文章
jquery 正则表达式
查看>>
mysql查询更新时的锁表机制分析(只介绍了MYISAM)
查看>>
JDBC如何调用存储过程
查看>>
扫盲记-第五篇--图像全景分割
查看>>
Haproxy安装与配置
查看>>
Linux之Ganglia源码安装
查看>>
Android中的Handler,Looper,Message机制
查看>>
Roman Numeral Converter
查看>>
魔幻之翼的博客
查看>>
java提高篇(四)-----理解java的三大特性之多态
查看>>
Python基础-----shelve模块
查看>>
文件发送成功率低的问题(1)
查看>>
异步方法 async/await
查看>>
37 数组的概念
查看>>
去掉SrollView、GrdiView、ListView、ViewPager等滑动到边缘的光晕效果
查看>>
我选择的……
查看>>
akka actor初探
查看>>
linux清理Java环境
查看>>
如何更改webstrom的默认端口63342
查看>>
最短路计数
查看>>