前言
前面,我已经写过一篇关于无限极分类的文章《无限级分类总结》。但在实际开发中,我可能不会选择那两种实现方法,而是选择另外一种更好的实现思路。前面那一种,在一个函数中通过递归实现所有分类的查询,虽然代码简单,思路明了,但因为每次递归都需要进行一次sql查询,效率上就不尽人意了,所以我会事先把所有的分类数据都查询出来,然后存储在一个数组中,构建树形数组结构,然后按层级显示,虽然代码繁琐,但查询效率上得到优化。下面是我在开发过程中使用的这种无限分类方式。
应用场景
在添加文章、商品过程中,需要将文章、商品分类有层次地展示。前台二、三级分类展示。
添加商品时的分类展示
分类表结构

代码
<?php
$link = mysqli_connect("localhost", "root", "root", "yiishop");
//获取所有数据,存储到一个数组中
function getAllCates($link)
{
$data = [];
$rows = mysqli_query($link, "select * from shop_category");
while ($row = mysqli_fetch_array($rows)) {
$data[] = $row;
}
return $data;
}
//对获取的数据按照树形进行排序
function getCates($cates, $pid = 0)
{
$result = [];
foreach ($cates as $cate) {
if ($cate['parentid'] == $pid) {
$result[] = $cate;
$result = array_merge($result, getCates($cates, $cate['cateid']));
}
}
return $result;
}
//使用前缀显示层级
function setPrefix($data, $prefix="|-")
{
$n = 1;
$path = [0=>1];
$tree = []; //一个带前缀的树,key为父id,值为层级
while ($current = current($data)) {
$key = key($data);
if ($key > 0) {
if ($data[$key-1]['parentid'] != $current['parentid']) {
$n++;
}
}
if (array_key_exists($current['parentid'], $path)) {
$n = $path[$current['parentid']];
} else {
$path[$current['parentid']] = $n;
}
$current['title'] = str_repeat($prefix, $n).$current['title'];
$tree[] = $current;
next($data);
}
return $tree;
}
//对格式进行修改,键为id,值为title
function getList($link)
{
$data = getAllCates($link);
$data = getCates($data);
$cates = setPrefix($data);
$result = [];
foreach ($cates as $cate) {
$result[$cate['cateid']] = $cate['title'];
}
var_dump($result);
}
getList($link);
效果显示
分类的前台展示
如何在前台展示分类呢?譬如:类似淘宝,京东的分类导航。实现思路是:将获取的分类数据拼凑成多维数组,然后通过循环遍历数组,可获得多级分类的前台展示。
代码
//将获取的分类数据拼凑成二维数组,循环遍历数组,可获取二级分类。
function showCates($link)
{
$data = [];
//获取所有的顶级分类
$rows = mysqli_query($link, "select * from shop_category where parentid=0");
while ($row = mysqli_fetch_array($rows)) {
//获取所有的二级分类
$rows2 = mysqli_query($link, "select * from shop_category where parentid=".$row['cateid']);
while ($r = mysqli_fetch_array($rows2)) {
$row['child'][] = $r;
}
$data['top'][] = $row;
}
//显示所有分类
var_dump($data);
}
showCates($link);
注:三级分类也是同样的做法,只不过拼凑的是三维数组。