#在日常的项目中,我们常常会接触到无限极分类。一般情况下无限极分类有两种实现的方式。第一种方式是通过数据表中的父ID。从而去一层一层地往上找。第二种方式是通过记录分类的全路径进行实现。接下来我将会根据两种不同的方法,通过编写小案例让您可以更快的理解和熟悉无限极分类。
#本次的代码案例实现是基于laravelDB操作数据库。因此这里调用的是直接的数据模型去获取数据。但是其实现的原理适用于各个框架与平台。
1.基于通过父级ID获取对应的无限极分类方法。
1.首先我们展示一下数据库的说明与建立
CREATE TABLE `deepcate` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pid` int(11) DEFAULT NULL,
`catename` varchar(11) DEFAULT NULL,
`cateorder` int(11) DEFAULT NULL COMMENT '排序字段',
`createtime` int(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
#分类表中 我们需要注意,我们要为对应的分类建立一个pid字段用于存储数据的上级ID2.为我们的数据表添加适当的测试数据
INSERT INTO `deepcate` VALUES (1,0,'新闻',0,0),(2,0,'图片',0,0),(3,1,'国内新闻',0,0),(4,1,'国外新闻',0,0),(5,2,'风景图片',0,0),(6,2,'美女图片',0,0),(7,4,'美国新闻',0,0),(8,3,'广东新闻',0,0),(9,5,'海滩风景',0,0),(10,6,'模特风采',0,0);
案例:1
编写获通过父ID方式取无限极分类列表的方法
编程思路:
1.获取所有的分类信息,并指定默认的顶级分类ID
2.遍历循环传入的数据,并判断当前的数据是否属于传入的顶级ID
3.如果判断为真则利用递归特性判断当前的数据中是否存在下级
4.如果完成判断,则返回输出的数据
//首先我们获取分类信息表中的所有数据并保存到变量$data中
$data=DB::table('deepcate')->get()->toarray();
//编写获取分类树的方法
/**
* 作者:逍遥侠
* 创建时间:2018/10/29
* @param int $pid 父级ID
* @param $data 传入的数据
* @param $level 当前的等级结构
* @return array 返回数据
*/
public function get_tree($pid=0,$data,$level){
//定义静态的数组存放变量
static $arr=[];
//遍历数据
foreach ($data as $k=>$v){
//判断当前遍历的数据的父级是否为传入的pid
if($v->pid==$pid){;
$arr[$k]['name']=$v->catename;
$arr[$k]['id']=$v->id;
$arr[$k]['level']=$level;
//判断当前数据中是否存在子分类,并给对应的结果+1
$this->get_tree($v->id,$data,$level+1);
}
}
return $arr;
}
#执行的结果
array:10 [▼
0 => array:3 [▼
"name" => "新闻"
"id" => 1
"level" => 0
]
2 => array:3 [▼
"name" => "国内新闻"
"id" => 3
"level" => 1
]
7 => array:3 [▼
"name" => "广东新闻"
"id" => 8
"level" => 2
]
3 => array:3 [▼
"name" => "国外新闻"
"id" => 4
"level" => 1
]
6 => array:3 [▼
"name" => "美国新闻"
"id" => 7
"level" => 2
]
1 => array:3 [▼
"name" => "图片"
"id" => 2
"level" => 0
]
4 => array:3 [▼
"name" => "风景图片"
"id" => 5
"level" => 1
]
8 => array:3 [▼
"name" => "海滩风景"
"id" => 9
"level" => 2
]
5 => array:3 [▼
"name" => "美女图片"
"id" => 6
"level" => 1
]
9 => array:3 [▼
"name" => "模特风采"
"id" => 10
"level" => 2
]
]案例:2
编写通过父ID方式获取面包屑导航
编程思路:
1.通过传入的ID获取对应的数据
2.判断数据是否为真,如果为真则保存对应需要的变量值,利用递归特性,传入该数据中的父级ID继续获取数据
//获取面包屑导航
$bread=$this->get_bread(10);
/**
* 作者:逍遥侠
* 创建时间:2018/10/29
* @param $id 传入的对应ID
* @return array
*/
public function get_bread($id){
//定义静态的数组存放变量
static $arr=[];
//根据传入的ID获取对应的分类信息
$res=DB::table('deepcate')->find($id);
//判断能否获取数据
if($res){
$data['name']=$res->catename;
$data['id']=$res->id;
array_push($arr,$data);
//传入该数据的父级ID作为查找元素判断是否存在
$this->get_bread($res->pid);
}
//重新排序
krsort($arr);
return $arr;
}
#执行结果
array:3 [▼
2 => array:2 [▼
"name" => "图片"
"id" => 2
]
1 => array:2 [▼
"name" => "美女图片"
"id" => 6
]
0 => array:2 [▼
"name" => "模特风采"
"id" => 10
]
]
2.基于全路径模式获取对应的无限极分类方法
1.首先我们展示一下数据库的说明与建立
CREATE TABLE `fullpath` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`path` varchar(255) DEFAULT NULL COMMENT '全路径',
`catename` varchar(255) DEFAULT NULL COMMENT '分类名称',
`cateorder` int(11) DEFAULT NULL COMMENT '排序',
`createtime` int(11) DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
2.为我们的数据表添加适当的测试数据
INSERT INTO `fullpath` VALUES (1,'','手机',0,0),(2,'1','功能手机',0,0),(3,'1.2','老人手机',0,0),(4,'1.2','儿童手机',0,0),(5,'1','智能手机',0,0),(6,'1.5','IOS手机',0,0),(7,'1.5','WinPhoto手机',0,0),(8,'1.5','android手机',0,0),(9,'1.2.4','色盲手机',0,0),(10,'1.2.3','大字手机',0,0);
案例:1
编写获通过全路径方式取无限极分类列表的方法
编程思路:
1.获取所有的分类数据,并按全路径字段排序
2.遍历数据,根据全路径的层级深度设定对应的级别层次
$full_tree=$this->get_full_tree();
/**
* 作者:逍遥侠
* 创建时间:2018/10/29
* @return mixed 返回数据
*/
public function get_full_tree(){
//获取所有的分类数据,并通过full字段排序
$data=DB::table('fullpath')->select(DB::raw('id,catename,path,concat(path,\'.\',id) as full'))->orderBy('full','asc')->get();
//遍历所有数据
foreach ($data as $k=>$v){
//根据过滤后的全路径字段获取对应的分类层级等级
$data[$k]->level=count(explode('.',trim($v->full,'.')));
}
return $data;
}
#注意由于我们数据表的字段是没有full这个字段的,所以我们使用mysql里的concat函数,利用对应的数据的path字段与id字段结合一个新的字段。该sql的原生写法为:
select id,path,catename,concat(path,'.',id) as full from `fullpath` order by full asc
#执行结果
Collection {#616 ▼
#items: array:10 [▼
0 => {#605 ▼
+"id": 1
+"catename": "手机"
+"path": ""
+"full": ".1"
+"level": 1
}
1 => {#606 ▼
+"id": 2
+"catename": "功能手机"
+"path": "1"
+"full": "1.2"
+"level": 2
}
2 => {#607 ▼
+"id": 3
+"catename": "老人手机"
+"path": "1.2"
+"full": "1.2.3"
+"level": 3
}
3 => {#608 ▼
+"id": 10
+"catename": "大字手机"
+"path": "1.2.3"
+"full": "1.2.3.10"
+"level": 4
}
4 => {#609 ▼
+"id": 4
+"catename": "儿童手机"
+"path": "1.2"
+"full": "1.2.4"
+"level": 3
}
5 => {#610 ▼
+"id": 9
+"catename": "色盲手机"
+"path": "1.2.4"
+"full": "1.2.4.9"
+"level": 4
}
6 => {#611 ▼
+"id": 5
+"catename": "智能手机"
+"path": "1"
+"full": "1.5"
+"level": 2
}
7 => {#612 ▼
+"id": 6
+"catename": "IOS手机"
+"path": "1.5"
+"full": "1.5.6"
+"level": 3
}
8 => {#613 ▼
+"id": 7
+"catename": "WinPhoto手机"
+"path": "1.5"
+"full": "1.5.7"
+"level": 3
}
9 => {#614 ▼
+"id": 8
+"catename": "android手机"
+"path": "1.5"
+"full": "1.5.8"
+"level": 3
}
]
}案例2:
编写获通过全路径方式取面包导航的方法
编程思路:
1.根据传入的ID获取对应ID
2.根据全路径字段,把字符串分割为数组
3.根据分割的数组,利用wherein方法获取包含的数据
$full_bread=$this->get_full_bread(10);
/**
* 作者:逍遥侠
* 创建时间:2018/10/29
* @param $id 传入的对应ID
* @return mixed 返回数据
*/
//获取全路径面包屑导航
public function get_full_bread($id){
//根据ID获取全路径的面包屑导航
$data=DB::table('fullpath')->select(DB::raw('id,catename,path,concat(path,\'.\',id) as full'))->orderBy('full','asc')->find($id);
//分割对应的全路径数组
$ids=explode('.',trim($data->full,'.'));
//根据分割的ID数组获取对应的数据
$bread=DB::table('fullpath')->wherein('id',$ids)->orderby('id','asc')->get();
return $bread;
}
#执行结果
Collection {#667 ▼
#items: array:4 [▼
0 => {#662 ▼
+"id": 1
+"path": ""
+"catename": "手机"
+"cateorder": 0
+"createtime": 0
}
1 => {#663 ▼
+"id": 2
+"path": "1"
+"catename": "功能手机"
+"cateorder": 0
+"createtime": 0
}
2 => {#664 ▼
+"id": 3
+"path": "1.2"
+"catename": "老人手机"
+"cateorder": 0
+"createtime": 0
}
3 => {#665 ▼
+"id": 10
+"path": "1.2.3"
+"catename": "大字手机"
+"cateorder": 0
+"createtime": 0
}
]
}