封装类:无限级分类的常用4种方法

1、无限级分类方法:组合一维数组

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 无限级分类方法:组合一维数组
public function unlimitedForLevel ($cate, $html='+  ', $pid=0, $level=0)
{
	$arr = array();
	foreach($cate as $v)
	{
		if($v['pid'] == $pid)
		{
			$v['level'] = $level + 1;
			$v['html'] = str_repeat($html, $level);
			$arr[] = $v;
			$arr = array_merge($arr, $this->unlimitedForLevel($cate, $html, $v['id'], $level+1));
		}
	}

	return $arr;
}

$arr的值:
unlimited_01

页面显示控制器代码(添加了翻页):

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public function index()
{
    // import("Org.Util.Category");
    $Cate = D('cata');
    $sortCate = new \Org\Util\Category();

    // 分页数据
    $count = $Cate->count();// 查询满足要求的总记录数
    $Page = new \Think\Page($count,10);// 实例化分页类 传入总记录数和每页显示的记录数(25)
    $show = $Page->show();// 分页显示输出

    // 进行分页数据查询 注意limit方法的参数要使用Page类的属性
    $list = $sortCate->unlimitedForLevel($Cate->limit($Page->firstRow.','.$Page->listRows)->order('sort')->select());
    $this->assign('list',$list);// 赋值数据集
    $this->assign('page',$show);// 赋值分页输出

    $this->display();
}

unlimited_02

2、无限级分类方法:组合多维数组
(常用于:导航,下拉导航)

还有另外一种方法;使用concat查询语句排序,见文章:SQL的CONCAT()函数实现无限级分类排序

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 无限级分类方法:组合多维数组
public function unlimitedForLayer ($cate, $pid=0)
{
	$arr = array();

	foreach($cate as $v)
	{
		if ($v['pid'] == $pid) {
			$v['child'] = $this->unlimitedForLayer($cate, $v['id']);
			$arr[] = $v;
		}
	}
	return $arr;
}

unlimited_03

3、面包屑导航:传递一个子分类ID返回所有的父类

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 面包屑导航:传递一个子分类ID返回所有的父类
public function getParents ($cate, $id)
{
	$arr = array();

	foreach($cate as $val)
	{
		if($val['id'] == $id)
		{
			$arr[] = $val;
			$arr = array_merge($this->getParents($cate, $val['pid']), $arr);
		}
	}
	return $arr;
}

unlimited_04

4、传递一个父ID,列出1个分类下的所有子分类ID

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public function getChildId($cate, $pid)
{
	$arr = array();

	foreach($cate as $val)
	{
		if($val['pid'] == $pid)
		{
			$arr[] = $val['id'];
			$arr = array_merge($arr, $this->getChildId($cate, $val['id']));
		}
	}
	return $arr;
}

unlimited_05

PHP实现无限级分类实例数据分析演示

无限级分类的数据库结构设计:
unlimited_catagories1

测试数据下载地址:
https://github.com/webjust/case-study/tree/master/unlimited%20catagories

测试数据库表结构:

Select Code
1
2
3
4
5
6
7
8
9
CREATE TABLE `shop_catalog` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `pid` int(11) unsigned NOT NULL,
  `name` varchar(255) NOT NULL,
  `title` varchar(255) NOT NULL,
  `description` varchar(255) NOT NULL,
  `path` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

在网页上显示的效果:
unlimited_catagories2

部分源代码如下:

第1步:从数据库遍历pid=0的分类

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php 
$conn = mysqli_connect('localhost', 'root', '', 'ishop') or die("数据库连接失败");
mysqli_set_charset($conn, 'utf8');

// 一级分类
$sql = "SELECT id,pid,name,path FROM `shop_catalog` WHERE `pid` = 0";
$res = mysqli_query($conn, $sql);
if ($res) {
	while($row = mysqli_fetch_assoc($res)){
		$cata1_list[] = $row;
	}
}
?>

第2步:嵌套循环遍历全部的分类

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php foreach($cata1_list as $val): ?>
<div style="width:180px; margin: 5px; float:left">
<div class="level01"><h1><?php echo $val['name'] ?></h1></div>
<div>
<?php 
	// 嵌套:遍历2级分类
	// 遍历父ID为上一级的ID的分类
	$sql2 = "SELECT id,pid,name,path FROM `shop_catalog` WHERE `pid` = {$val['id']}";
	// echo $sql;
	$res2 = mysqli_query($conn, $sql2);
	$cata2_list = [];
	if ($res2) {
		while ($row2 = mysqli_fetch_assoc($res2)){
			$cata2_list[] = $row2;
		}
	}
	foreach($cata2_list as $val2):
?>
	<div style="border:1px solid #ddd; margin-bottom:10px; padding:10px;">
	<div class="level02"><h2><?php echo $val2['name']; ?></h2></div>

	<?php 
		// 嵌套:遍历3级分类
		$sql3 = "SELECT id,pid,name,path FROM `shop_catalog` WHERE `pid` = {$val2['id']}";
		$res3 = mysqli_query($conn, $sql3);
		$cata3_list = [];
		if ($res3) {
			while ($row3 = mysqli_fetch_assoc($res3)){
				$cata3_list[] = $row3;
			}
		}
		// print_r($cata2_list);
		foreach($cata3_list as $val3):
	?>
		<a href="./catalog.php?cid=<?php echo $val3['id'] ?>" class="level03"><?php echo $val3['name'] ?></a>
	<?php endforeach ?>
	</div>
<?php endforeach; ?>
</div>
</div>
<?php endforeach;?>