thinkphp5.0无限极分类及格式化输出
首先我们来看数据表
从上图中可以发现,中国下有贵州,北京两个子节点,而北京有天安门一个子节点,纽约的子节点是“纽约的子类”。
从pid为0看出,中国和纽约是顶级节点。
因为贵州的pid是1,而中国的id为1,所以贵州的父节点是中国,至于type字段,可以不用管,只是我自己的项目需要。
可以发现,着写数据在数据表中是无序的,并没有我们想象中的层次结构分明并且可读性很好。
那么,当使用无限极分类之后数据的输出是怎样的呢?如下:
这样就能够很清晰的看出他们的层次结构了,那么这样的效果在thinkphp5.0是怎么实现的呢?
好了,贴出代码:
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2017/9/24
* Time: 17:14
*/ namespace app\admin\model;
use think\Model;
class Cate extends Model
{
public function cateTree(){
$res=$this->select();
if($res){
$result=$this->sort($res);
return $result;
}
}
public function sort($data,$pid=0,$level=0){
//此处数据必须是静态数组,不然递归的时候每次都会声明一个新的数组
static $arr=array();
foreach ($data as $key=>$value){
if($value['pid'] == $pid){
$value["level"]=$level;
$arr[]=$value;
$this->sort($data,$value['id'],$level+1);
}
}
return $arr;
}
}
首先我们可以看到,在cateTree方法中我们通过select()方法获取到了数据库里面的所有数据,然后将数据传入到sort里面,此刻我们注意到sort有三个参数,pid表示当前节点的父节点的id,level表示当前节点
为几级。(顶级节点是0级,顶级节点的子节点是1级),那么level的用处到时候输出的时候会用到,此处不用纠结。
当数据传入sort方法之后,声明一个静态数组,保证每次递归调用的时候数组里面的数据不会改变,然后循环从数据库里面查询的数据。
$value的值表示数据库里面的一行,是一个数组,$value['名字']表示一行里面的一个字段。
首先我们通过
$value['pid'] == $pid
判断当前的pid是否为0,因为我们在sort方法一开始的时候就给了一个默认值0,此时$pid为0。 这样做的目的就是选出第一个顶级节点。 如果找到了第一个顶级节点,假如是中国,那么满足if的条件,就进入条件体,先给$value数组加一个level值,然后再把$value整个假如到静态数组当中去。 然后开始递归,注意,此刻sort方法的pid参数接受的是当前节点的id。为什么要这样传呢? 举个例子: 如果我们循环到了中国,如下图
第一次递归的时候,会将static 数组入栈,以及将变量入栈,并保存程序的断点,以便递归完成之后能够顺利的找到进入递归出并继续执行程序。 如上图,找到中国后,递归,入栈,此刻静态数组里面只有“中国”一个数据。(注意:数组是一个二维数组,我只是为了简便才画了一维数组,数组里面还包含了level的信息)。通过pid判断中国下方是否有子节点,然后匹配到贵州之后,进入递归,数据入栈。此时静态数组里面又增加了贵州这个数据。 到了贵州之后,发现在我们的数据表里面并没有贵州的子节点,此时递归结束,程序返回递归入口处,继续执行循环体,栈空间如下:
当递归回来时,贵州出栈,此时栈空间里面保存的是中国的数据,包括pid为0这个变量,level为0这个变量,以及静态数组。当执行下一个循环时,$value['pid'] == $pid
因为栈空间里面保存的pid是0,所以会找到北京这个数据。
接下来的步骤就差不多了,首先foreach循环天安门的子节点,发现没有子节点,递归结束,同时将sort($data,7,3)出栈,回到递归进入出,以上为例,则回到天安门那段代码的sort处,同时执行foreach循环,查找是否有其他的节点的pid为6,即查看北京下是否还有其他子节点。如果有,则将该节点的数据入栈,如果没有则出栈,回到北京那块代码的sort处,匹配pid为1的是否还有其他节点。如果没有则回到最开始的sort处,此时递归完全结束。
此刻我们来观察数组,可以看出,通过递归,数组里的数据开始变得有序起来,如贵州是中国的一级子节点,所以紧跟在中国之后,当第一轮递归结束,到了第二轮递归时,第一个找到的是北京,所以数组里面第三个元素是北京。
那怎么得到如下的格式化数据呢?
我们可以发现,北京和贵州的level是相同的,注意:我们的数组还保存得有level信息(图中的level有些错误,不建议大家参考)。
level数值大的前面的短线就越多,表示级数就越大。
那么这是怎么输出的呢?
{volist name="cateList" id="cate"}
<!--设置URL值,方便JS删除的时候获取路径-->
<tr id="{:url('delete',array('id'=>$cate.id))}" class="url">
<td align="center">{$cate.id}</td>
<td><?php echo str_repeat("-",$cate["level"]*8)?>{$cate.cate_name}</td>
{/volist}
以上是thinkphp的模板标签,volist和foreach是一样的道理
通过后台分配而来的cateList数据(也就是上面的静态数组),通过
<td><?php echo str_repeat("-",$cate["level"]*8)?>{$cate.cate_name}</td>
得到最终的结果。
thinkphp5.0无限极分类及格式化输出的更多相关文章
- C#无限极分类树-创建-排序-读取 用Asp.Net Core+EF实现
今天做一个管理后台菜单,想着要用无限极分类,记得园子里还是什么地方见过这种写法,可今天找了半天也没找到,没办法静下心来自己写了: 首先创建节点类(我给它取名:AdminUserTree): /// & ...
- PHP无限极分类生成树方法,无限分级
你还在用浪费时间又浪费内存的递归遍历无限极分类吗,看了该篇文章,我觉得你应该换换了.这是我在OSChina上看到的一段非常精简的PHP无限极分类生成树方法,巧在引用,整理分享了. function g ...
- PHP无限极分类实现
简单版的PHP生成无限极分类代码.其中包括了数据库设计.以及输出分类HTML代码. SQL代码 CREATE TABLE `district` ( `id` int(10) unsigned NOT ...
- PHP无限极分类生成树方法
你还在用浪费时间又浪费内存的递归遍历无限极分类吗,看了该篇文章,我觉得你应该换换了.这是我在OSChina上看到的一段非常精简的PHP无限极分类生成树方法,整理分享了. function genera ...
- 分享一个牛逼的PHP无限极分类生成树方法,巧用引用(转)
你还在用浪费时间又浪费内存的递归遍历无限极分类吗,看了该篇文章,我觉得你应该换换了.这是我在OSChina上看到的一段非常精简的PHP无限极分类生成树方法,巧在引用,整理分享了. function g ...
- php 实现无限极分类
原始数据 $array = array( array('id' => 1, 'pid' => 0, 'n' => '河北省'), array('id' => 2, 'pid' ...
- PHP实现无限极分类的两种方式,递归和引用
面试的时候被问到无限极分类的设计和实现,比较常见的做法是在建表的时候,增加一个PID字段用来区别自己所属的分类 $array = array( array('id' => 1, 'pid' =& ...
- php无限极分类以及递归(thinkphp)
php无限极分类: 无限极分类重点在于表的设计: 1在model中: class CatModel extends Model{ protected $cat = array(); public fu ...
- js实现无限极分类
转载注明出处!!! 转载注明出处!!! 转载注明出处!!! 因为要实现部门通讯录,后台传来的数据是直接从数据库里拿的部门表,所以没有层级分类,只有parentId表示从属关系,所以分类的事情就交给我来 ...
随机推荐
- 1_NAT模式和桥接模式下的网络配置
相信当你看到这篇文章时,你一定对linux的桥接模式和NAT模式有所了解,所以你应该是能看懂这篇文件的,希望对你有所帮助,figthing ! 一.桥接模式:虚拟机和主机是连在同一个路由下的. ...
- java中 this 的三种用法
Java中this的三种用法 调用属性 (1)this可以调用本类中的任何成员变量 调用方法(可省略) (2)this调用本类中的成员方法(在main方法里面没有办法通过this调用) 调用构造方法 ...
- Struts2使用自定义拦截器导致Action注入参数丢失、url参数
写struts2项目时发现前台超链接中的参数无法传到action, 所有带有传递参数的均无法正常使用了,在Action中所有的参数无法被注入. 后来经过debug发现其中的页面都要先经过拦截器,而后再 ...
- [2012-06-21]结合find的awk
源起:http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=3754423&page=1&extra=#pid221729 ...
- jq获取图片的原始尺寸,自适应布局
原理: each()遍历,width().height()获取宽高, load() 注意: 由于页面加载完了,但图片不一定加载完了,所以直接通过 $("img").width(), ...
- Docker打包 Asp.Net Core应用,在CentOS上运行
本文主要介绍下运用docker虚拟技术打包Asp.net core应用. Docker作为一个开源的应用容器引擎,近几年得到广泛的应用,使用Docker我们可以轻松实现应用的持续集成部署,一次打包,到 ...
- 定时调度框架:Quartz.net
Quartz.net相关概念 经常出现场景:定时轮询数据库同步,定时邮件通知,定时处理数据等 Scheduler (计划者或调度器) Job (工作对象):将要定时执行的任务代码写到实现Ijob接口的 ...
- webStrom2017.1版本如何添加vue.js插件
第一步:打开webStrom-setting 第二步:选择File and Code Templates--点击左上角"+"号 第三步:在Name:vue File Exte ...
- CVE-2016-10190 FFmpeg Http协议 heap buffer overflow漏洞分析及利用
作者:栈长@蚂蚁金服巴斯光年安全实验室 -------- 1. 背景 FFmpeg是一个著名的处理音视频的开源项目,非常多的播放器.转码器以及视频网站都用到了FFmpeg作为内核或者是处理流媒体的工具 ...
- selenium chromedriver与谷歌浏览器版本映射表 (更新至v2.32)
----------ChromeDriver v2.32 (2017-08-30)---------- Supports Chrome v59-61最新的ChromeDriver 2.32 支持谷歌浏 ...