php无限分类也可以实现网站导航的效果,例如1688的官网头部导航:

测试数据:

    const arr = [['id' => 1, 'pid' => 0, 'city' => '江西'],['id' => 2, 'pid' => 0, 'city' => '广东'],['id' => 3, 'pid' => 1, 'city' => '宜春'],['id' => 4, 'pid' => 3, 'city' => '丰城'],['id' => 5, 'pid' => 4, 'city' => '尚庄'],['id' => 6, 'pid' => 2, 'city' => '深圳'],['id' => 7, 'pid' => 6, 'city' => '翻身'],#以下是追加的同级元素数据,用来试验论证,也是增强干扰性['id' => 8, 'pid' => 1, 'city' => '南昌'],['id' => 9, 'pid' => 8, 'city' => '高新区'],];

思路分析:

传入一个顶级pid  ,只有当pid为0时,才是顶级,故pid的值为0。

根据pid找到当前类别的数据,得到当前类别的id,以此当作当前类别的子类pid传入。

继续重复刚刚上面这个行为,直到找不到子类为止,则跳出当前类别的查找,继续下一个类别的查找。

也就是:传入pid = 0 ,只有id为1和id为2的江西和广东符合条件。

1.先处理江西,再找到宜春和南昌,

2.先处理宜春,再根据宜春找到丰城,再根据丰城找到尚庄,再根据尚庄去找发现没有子级,跳出宜春;

3.宜春处理完毕后,来处理与之同级的南昌;根据南昌找到高新区,根据高新区去找发现没有子级,跳出南昌来到江西。

4.此时发现江西的子类宜春和南昌处理完毕,跳出来到最顶级的广东。

4.根据广东,找到深圳,再根据深圳找到翻身,根据翻身去找发现没有子级,再跳出,发现所有数据处理完毕,程序结束。

根据上面的思路得知,这是一个可以无限调用自身的方法,也就是递归来处理。

代码实践:

下列将逐渐迭代版本,以帮助理解。

唠叨一下:

网上的例子大多都是给出一个最终版叫人去看,不过我想如果你能看到我这篇文章,多半也和我一样看了也不明所以,所以还是自己写一个熟悉的层级关系数组来实践为好。

首先要明白的思路是:声明一个数组,用这个数组去存储每次得到的分类返回值,再将这个分类返回值以键名child在它的父级中以元素的形式插入该数据,如此往复,得到一个完整的层级关系大数组。

版本一:

public function test(array $data , $pid = 0){$array = [];foreach ($data as $key => $value) {//找到当前分类的下一级(子级)if($value['pid'] == $pid){$array[$value['id']] = $value;  $array[$value['id']]['child'] = $this->test($data,$value['id']);}}return $array;}

效果如下:

这一版需理解大概思路是:

1.传入了顶级数据(我此刻就是顶级数据,也就爷爷!) , 然后声明了$array这个数组存储每一个孙子的数据并返回

2.使用$array去存储当前分类子级(我儿子)的数据

3.(我)儿子可能不止一个,可能有很多个,所以需要使用每个儿子的id作为键名来存储每个儿子的值,保证每个儿子的数据不会乱套,即$array[$value['id']] = $value;

如果使用$pid或者$key去作键名存储,要意识到:这两玩意是会重复的不具备唯一性,这样就导致每个儿子的数据乱了,可能后面的儿子和前面的儿子键名都一样,后者把前者覆盖了,这就尴尬了!所以这两玩意不能作为键名存储儿子的数据。

4.那我有了儿子的数据,我也得有儿子的儿子(孙子)的数据哇。那孙子的数据怎么来呢?

这简单,把儿子的id继续往自身函数里一丢再返回出来不就得到了吗?于是此时递归产生了....

5.通过递归,我找到了孙子的数据,并且也把孙子的数据返回了出来;那我得把孙子的数据丢到儿子的数据里吧?孙子的名字在儿子那叫什么好呢?有了,就叫child吧!哈哈孩子!

所以就出现了$array[$value['id']]['child'] = $this->test($data,$value['id']);

6.诶?神奇的一幕发生了,我作为爷爷,拿到了儿子的数据,也通过递归拿到了孙子的数据。但是我的孙子还有儿子和孙子哇,所以在把儿子的id继续往自身一丢的时候,我的(每个)儿子就成了曾孙们的爷爷!再如此往复...我的曾孙们也成为了爷爷!

这样就出现了一个分类关系:我就是祖宗,我的儿子们是二代,我的孙子们是三代;

但是我的儿子和孙子们要想得到它们子辈数据,就得像我一样成为爷爷才行,也就是说:每一个分类都应该以child为键名存储它的子级(儿子)。

在第一次传入顶级pid=0,得到$array(子级) , $array[$value['id']]['child'](孙子级)

递归开始:

第二次传入:儿子id=1 ,得到$array(曾孙), $array[$value['id']]['child'](曾曾孙)

无限递归中....

第n次传入:没有子级了,好了,我已经是家族里目前最小的孩子了(没有比我更小的了!),我本身的数据是$array,该把$array塞到我的父级以child为键名的元素中去了...欸?我的父亲还有父亲,我的父亲要把它的数据给他的父亲(我的爷爷)...欸?我的爷爷还有父亲,我爷爷的父亲也该把数据给他的父亲(我的曾曾曾祖父)...如此往复...这样逐渐自下往上提交数据,最顶级的人就拿到了整个家族的数据(整个分类)了!

7.如果你觉得上面的关系太过复杂,可以看下列:

从1到100

1 2 3 4 5 6 7 8 9 10 ... 100

我此刻是1,我的下一位数是2,我的下下位是3,再多我就不知道了。

也就是1['child'] = 2 , 2['child'] = 3

既然我不知道,那我就让我的儿子来呗,也就是让2来。

此刻我是2,我的下一位是3,我的下下位是4,再多我就不知道了。

也就是2['child'] = 3 , 3['child'] = 4

既然我不知道,那我就让我的儿子来呗,也就是让3来。

........

直到这样:

此刻我是99,我的下一位是100,我的下下位没有了!

也就是99['child'] = 100 , 100['child'] = ‘’

啊,原来在我们家100是尽头了啊...那我要开始汇报了

99['child'] =[

100['child'] = ‘’

]

98['child'] =[

99['child'] = [

100['child'] = ‘’

]

]

如此往复:

最终得到:

1['child'] =[

2['child'] = [

3['child'] = [

..........

100['child'] = ‘’

]

]

]

与上面的版本一也是同理,传入顶级id,找到最小的分类,再从最小的分类开始自下而上逐级塞入child值,最后顶级id所在的数组就拿到了整个大数组数据。

版本二:

    public function test(array $data , $pid = 0){$array = [];foreach ($data as $key => $value) {if($value['pid'] == $pid){$value['child'] = $this->test($data,$value['id']);$array[]= $value;}}return $array;}

仔细查看版本一发现:最终都是将$value的数组塞入$array中,那只要得到当前分类以child为键名的子级数据再塞入$array中就好了呀,于是出现了

$value['child'] = $this->test($data,$value['id']);
 $array[]= $value;

效果如下:

小影响:与第一版不同的是,键名元素都变成了0

版本三:

在版本二的基础上,加入了if判断是否有子级分类的数据,如果有才以child为键名,递归值为键值。

    public function test(array $data , $pid = 0){$array = [];foreach ($data as $key => $value) {if($value['pid'] == $pid){$childData = $this->test($data,$value['id']); //得到孙子的数据if(!empty($childData)){ //孙子的数据不为空,才把孙子的数据以child为键塞入儿子数组中$value['child'] = $childData;   }$array[]= $value;}}return $array;}

页面渲染完整代码:

最后因为网站导航一般都是双层关系,也就是只需要两个循环即可完成。一个循环一级分类,另一个循环子级分类,最后拼接html,返回前端渲染即可。

    <?php
/*** Created by phpStrom* User: Anbin* Date: 2022/8/31* Time: 16:48*/class Nav
{//测试数据const arr = [['id' => 1, 'pid' => 0, 'city' => '江西'],['id' => 2, 'pid' => 0, 'city' => '广东'],['id' => 3, 'pid' => 1, 'city' => '宜春'],['id' => 4, 'pid' => 3, 'city' => '丰城'],['id' => 5, 'pid' => 4, 'city' => '尚庄'],['id' => 6, 'pid' => 2, 'city' => '深圳'],['id' => 7, 'pid' => 6, 'city' => '翻身'],#以下是追加的同级元素数据,用来试验论证,也是增强干扰性['id' => 8, 'pid' => 1, 'city' => '南昌'],['id' => 9, 'pid' => 8, 'city' => '高新区'],];/*** 传入数据得到导航栏html* @param array $data* @return string*/public function getNav(array $data):string{$str = '';foreach ($data as  $value) {$str .= '<h2>' . $value['city'] . '</h2>'; //导航一级菜单$str .= '<ul>';if (isset($value['child'])) { //二级菜单(若存在)foreach ($value['child'] as $k => $item) {$str .= '<li>' . $item['city'] . '</li>';}}$str .= '</ul>';}return $str;}/*** 无限分类得到子孙关系大数组* @param array $data* @param int $pid* @return array*/public function test(array $data, $pid = 0){$array = [];foreach ($data as $value) {if ($value['pid'] == $pid) {$childData = $this->test($data, $value['id']); //得到孙子的数据if (!empty($childData)) { //孙子的数据不为空,才把孙子的数据以child为键塞入儿子数组中$value['child'] = $childData;}$array[] = $value;}}return $array;}/*** 查看页面效果* @return string*/public function index(){$res = $this->test(self::arr);if (!empty($res)) {return $this->getNav($res);}}
}
$a = new Nav();
echo $a->index();

php无限分类之网站导航相关推荐

  1. php无限分类之面包屑导航

    面包屑导航:网站中用于展示页面层级关系的导航栏,同时也可以清楚的告知用户它当前身处于哪个位置(层级),以确定网站的结构和增强用户浏览体验. 简单示例: 这里以php手册为例,展示一个简单的面包屑导航. ...

  2. PHP全路径无限分类导航LINK代码实现

    <?php/*** @param php全路径无限分类*/include('db.inc.php'); function getPathCate($cateid){$sql = "se ...

  3. 如何设计网站导航更利于SEO优化?

    网站SEO优化都会做站内站外的优化,清晰的导航结构对于网站建设来说至关重要,导航优化也是优化人员重视的优化作业,优质的导航对于网站结构以及用户体验都有很大的帮助,让用户清楚的知道自己的所在的位置以及起 ...

  4. 步进电机无细分和20细分_细分网站导航会话

    步进电机无细分和20细分 目标与应用 (Goal and applications) This article will show a method for segmenting website na ...

  5. Php xml 目录,PHP-PHP+xml的无限分类树目录的方法?

    无限分类树的代码有很多,下面是个示例: /** by lenush; */ class Tree { var $data = array(); var $child = array(-1=>ar ...

  6. 御用导航提示页面_UI网站导航设计知识与五个知识案例

    导航设计是网站的基石.它确定了至关重要的指标,例如转化率和跳出率,页面停留时间,点击量,并且通常是决定您的访问者拥有良好体验并以比您所说的"用户流量"更快退出网站的决定性因素. 但 ...

  7. concat php,php基于concat实现无限分类

    这篇文章主要介绍了php无限分类使用concat是如何实现的,需要的朋友可以参考下 一.数据库设计 -- -- Table structure for table `category` -- CREA ...

  8. 仿花生小说蓝色小说网站导航网站源码

    简介: 帝国cms7.5仿花生小说蓝色小说网站导航网站源码 带手机版 一个专注小说阅读细化分类的网站. 会根据不同的用户喜好,将海量的小说进行细化的专题分类,让您更快的找到自己喜欢的小说阅读. 另外, ...

  9. 仿小说蓝色小说网站导航引流网站源码 带手机版

    介绍: 帝国cms7.5仿花生小说蓝色小说网站导航网站源码 带手机版一个专注小说阅读细化分类的网站. 我们会根据不同的用户喜好,将海量的小说进行细化的专题分类,让您更快的找到自己喜欢的小说阅读. 另外 ...

最新文章

  1. GitHub上大热的Deep Photo终于有TensorFlow版了!
  2. 【Android 应用开发】Paint 滤镜原理 之 颜色矩阵 ( 颜色模式 | 颜色通道 | 颜色矩阵 | 矩阵运算 | 矩阵乘法 | 矩阵加法 | 颜色矩阵深入解析 )
  3. 【Linux多线程】三个经典同步问题
  4. C++new和delete实现原理(汇编解释)
  5. MDP马尔可夫决策过程(二)
  6. corn表达式的简单使用
  7. 设计模式之组合模式(十四)
  8. Python urllib HTTP头注入漏洞
  9. unity插件共享汇总大全
  10. 数字图像处理技术对军事与公安的帮助
  11. 职称计算机为啥要现场拍照,网上确认/现场确认的照片还没拍?你需要这份拍照攻略!...
  12. uv纹理坐标设定与贴图规则
  13. C++项目 GitHub Actions操作实例
  14. oppo便签误删怎么办_oppo手机便签误删怎么办?oppo便签如何导入新手机
  15. 2016级移动应用开发在线测试14-MediaPlayer
  16. java面试题(一)java面试题集合
  17. string的常用方法(详细)
  18. 基于聚类(Kmeans)算法实现客户价值分析系统(电信运营商)
  19. Arch Linux 安装
  20. 使用dos命令行启动服务

热门文章

  1. IGES格式文件举例
  2. ACM-ICPC 2018 南京赛区网络预赛:E :AC Challenge题解
  3. C语言计算出结构体所占空间大小
  4. python内置模块re_13.python内置模块之re模块
  5. 使整个网站变黑白(灰色)的特效代码
  6. Krpano学习:在javascript中动态添加/删除/修改(位置)热点(向后端写入)
  7. Incorrect string value: ‘‘\\xE5\\x87\\xBA\\xE4\\xBB\\xBB...‘‘ for column ‘‘note_describe‘‘ at row 1
  8. 华云数据董事长许广彬接受中央电视台采访:推动职业教育发展 打造信创人才核心竞争力
  9. zenmap使用教程
  10. 基于C++的云安全主动防御系统客户端服务端设计