PHP无限级分类是后台开发中非常实用的功能,能够支持无限层级的分类嵌套,适配各类需要层级管理的业务场景。实现该功能的核心在于合理的数据库表设计和对应的数据处理逻辑。
数据库表设计
无限级分类的表结构需要包含自关联字段,用于标识当前分类的父级分类。以下是基础的表结构设计:
CREATE TABLE `category` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL COMMENT '分类名称', `parent_id` int(11) NOT NULL DEFAULT '0' COMMENT '父级分类ID,0表示顶级分类', `sort` int(11) NOT NULL DEFAULT '0' COMMENT '排序权重', PRIMARY KEY (`id`), KEY `idx_parent_id` (`parent_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='无限级分类表';
递归方式实现无限级分类
递归是最直观的实现方式,通过不断调用自身函数查询子分类,适合分类层级不深的场景。以下是完整的实现代码:
<?php
// 模拟从数据库查询到的分类数据
$categoryList = [
['id' => 1, 'name' => '电子产品', 'parent_id' => 0, 'sort' => 1],
['id' => 2, 'name' => '手机', 'parent_id' => 1, 'sort' => 1],
['id' => 3, 'name' => '电脑', 'parent_id' => 1, 'sort' => 2],
['id' => 4, 'name' => '苹果手机', 'parent_id' => 2, 'sort' => 1],
['id' => 5, 'name' => '华为手机', 'parent_id' => 2, 'sort' => 2],
['id' => 6, 'name' => '笔记本', 'parent_id' => 3, 'sort' => 1],
['id' => 7, 'name' => '服装', 'parent_id' => 0, 'sort' => 2],
['id' => 8, 'name' => '男装', 'parent_id' => 7, 'sort' => 1],
];
/**
* 递归获取指定父级ID下的所有子分类
* @param array $allList 所有分类数据
* @param int $parentId 父级分类ID
* @param int $level 当前层级
* @return array 处理后的分类数组
*/
function getChildCategory($allList, $parentId = 0, $level = 0) {
$result = [];
foreach ($allList as $item) {
if ($item['parent_id'] == $parentId) {
$item['level'] = $level;
$item['child'] = getChildCategory($allList, $item['id'], $level + 1);
$result[] = $item;
}
}
return $result;
}
// 获取顶级分类下的所有层级数据
$treeData = getChildCategory($categoryList);
// 打印结果查看结构
echo '<pre>';
print_r($treeData);
echo '</pre>';
引用方式实现无限级分类
递归方式在层级过深时可能出现栈溢出问题,引用方式通过数组引用的特性处理,效率更高,适合层级较深的场景。实现代码如下:
<?php
// 使用上面的模拟分类数据
$categoryList = [
['id' => 1, 'name' => '电子产品', 'parent_id' => 0, 'sort' => 1],
['id' => 2, 'name' => '手机', 'parent_id' => 1, 'sort' => 1],
['id' => 3, 'name' => '电脑', 'parent_id' => 1, 'sort' => 2],
['id' => 4, 'name' => '苹果手机', 'parent_id' => 2, 'sort' => 1],
['id' => 5, 'name' => '华为手机', 'parent_id' => 2, 'sort' => 2],
['id' => 6, 'name' => '笔记本', 'parent_id' => 3, 'sort' => 1],
['id' => 7, 'name' => '服装', 'parent_id' => 0, 'sort' => 2],
['id' => 8, 'name' => '男装', 'parent_id' => 7, 'sort' => 1],
];
/**
* 引用方式生成分类树
* @param array $list 所有分类数据
* @return array 树形结构数据
*/
function generateCategoryTree($list) {
$tmpData = [];
// 先将所有数据以ID为键存入临时数组
foreach ($list as $item) {
$tmpData[$item['id']] = $item;
$tmpData[$item['id']]['child'] = [];
}
$tree = [];
foreach ($tmpData as $item) {
if ($item['parent_id'] == 0) {
// 顶级分类直接放入树
$tree[] = &$tmpData[$item['id']];
} else {
// 非顶级分类放入对应父级的child数组
$tmpData[$item['parent_id']]['child'][] = &$tmpData[$item['id']];
}
}
return $tree;
}
$treeResult = generateCategoryTree($categoryList);
echo '<pre>';
print_r($treeResult);
echo '</pre>';
前端展示示例
获取到树形结构数据后,可以在前端通过递归渲染展示层级关系,以下是简单的HTML展示代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>无限级分类展示</title>
<style>
.category-item { margin-left: 20px; }
</style>
</head>
<body>
<?php
// 假设$treeData是前面递归方式得到的树形数据
function renderCategory($data) {
echo '<ul>';
foreach ($data as $item) {
echo '<li class="category-item">' . $item['name'];
if (!empty($item['child'])) {
renderCategory($item['child']);
}
echo '</li>';
}
echo '</ul>';
}
renderCategory($treeData);
?>
</body>
</html>
注意事项
- 数据库查询时如果分类数据量较大,建议先一次性查询所有数据再在PHP中处理,避免多次查询数据库影响性能。
- 递归方式的层级深度受PHP配置的最大递归深度限制,默认是100层,超过该深度需要调整配置或改用引用方式。
- 实际开发中可以根据需求给分类表增加更多字段,比如分类图片、状态、描述等,处理逻辑保持一致即可。