php 获取无限分类

admin 104 0
PHP实现无限分类通常采用树形结构存储数据,数据库表设计包含id(分类ID)、pid(父分类ID)、name(分类名称)等字段,核心思路是通过递归或迭代方式构建层级关系:先获取所有分类数据,再以pid为键分组,递归遍历每个父节点及其子节点,生成树形结构,递归法代码简洁但层级过深可能栈溢出,迭代法(如引用法)效率更高,最终可输出多维数组或HTML结构(如下拉菜单、面包屑),适用于商品分类、文章栏目等场景,灵活实现无限层级分类的展示与管理。

PHP 实现无限分类数据的获取与处理详解

管理系统、权限管理、商品分类等业务场景中,分类结构往往存在层级嵌套(如"电子产品 > 手机 > 智能手机"),这种"无限级分类"的设计需要高效的数据存储与查询方法,本文将详细介绍 PHP 中如何实现无限分类数据的获取,包括核心思路、代码实现及优化技巧。

无限分类的核心:数据存储结构

无限分类的关键在于如何用二维表存储层级关系,最常用的方式是 邻接表模型(Adjacency List),即在分类表中添加 parent_id 字段,记录当前分类的父级分类 ID(根分类的 parent_id 通常为 0 或 NULL)。

示例数据表结构

CREATE TABLE `categories` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL COMMENT '分类名称',
  `parent_id` int(11) NOT NULL DEFAULT '0' COMMENT '父级分类ID,0为顶级分类',
  `level` int(11) NOT NULL DEFAULT '1' COMMENT '分类层级(可选,用于优化查询)',
  `sort` int(11) NOT NULL DEFAULT '0' COMMENT '排序字段',
  `path` varchar(255) NOT NULL DEFAULT '' COMMENT '分类路径(可选,用于优化查询)',
  `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态:1-启用,0-禁用',
  PRIMARY KEY (`id`),
  KEY `idx_parent_id` (`parent_id`),
  KEY `idx_path` (`path`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

示例数据

id name parent_id level sort path status
1 电子产品 0 1 100 1 1
2 服装 0 1 90 2 1
3 手机 1 2 80 1,3 1
4 电脑 1 2 70 1,4 1
5 智能手机 3 3 60 1,3,5 1
6 功能机 3 3 50 1,3,6 1
7 笔记本 4 3 40 1,4,7 1
8 台式机 4 3 30 1,4,8 1

获取无限分类的常见方法

方法1:递归查询(内存构建树形结构)

思路
  1. 先查询所有分类数据(按 parent_id 排序,便于后续处理);
  2. 遍历所有分类,以 id 为 key、分类信息为 value 构建索引数组;
  3. 递归遍历每个分类,将其子分类(通过 parent_id 匹配)挂载到 children 字段中。
代码实现
<?php
/**
 * 递归构建无限分类树
 * @param array $categories 所有分类数据(按parent_id排序)
 * @param int $parentId 父级分类ID,默认0为顶级分类
 * @return array 树形结构分类
 */
function buildTreeRecursive(array $categories, int $parentId = 0): array
{
    $tree = [];
    foreach ($categories as $category) {
        if ($category['parent_id'] == $parentId) {
            // 递归获取子分类
            $children = buildTreeRecursive($categories, $category['id']);
            if (!empty($children)) {
                $category['children'] = $children;
            }
            $tree[] = $category;
        }
    }
    return $tree;
}
// 模拟数据库查询(实际项目中可用 PDO/MySQLi 查询)
$categories = [
    ['id' => 1, 'name' => '电子产品', 'parent_id' => 0, 'level' => 1],
    ['id' => 2, 'name' => '服装', 'parent_id' => 0, 'level' => 1],
    ['id' => 3, 'name' => '手机', 'parent_id' => 1, 'level' => 2],
    ['id' => 4, 'name' => '电脑', 'parent_id' => 1, 'level' => 2],
    ['id' => 5, 'name' => '智能手机', 'parent_id' => 3, 'level' => 3],
    ['id' => 6, 'name' => '功能机', 'parent_id' => 3, 'level' => 3],
    ['id' => 7, 'name' => '笔记本', 'parent_id' => 4, 'level' => 3],
    ['id' => 8, 'name' => '台式机', 'parent_id' => 4, 'level' => 3],
];
// 构建树形结构
$categoryTree = buildTreeRecursive($categories);
// 输出结果(json格式,方便调试)
header('Content-Type: application/json');
echo json_encode($categoryTree, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
输出结果
[
    {
        "id": 1,
        "name": "电子产品",
        "parent_id": 0,
        "level": 1,
        "children": [
            {
                "id": 3,
                "name": "手机",
                "parent_id": 1,
                "level": 2,
                "children": [
                    {
                        "id": 5,
                        "name": "智能手机",
                        "parent_id": 3,
                        "level": 3
                    },
                    {
                        "id": 6,
                        "name": "功能机",
                        "parent_id": 3,
                        "level": 3
                    }
                ]
            },
            {
                "id": 4,
                "name": "电脑",
                "parent_id": 1,
                "level": 2,
                "children": [
                    {
                        "id": 7,
                        "name": "笔记本",
                        "parent_id": 4,
                        "level": 3
                    },
                    {
                        "id": 8,
                        "name": "台式机",
                        "parent_id": 4,
                        "level": 3
                    }
                ]
            }
        ]
    },
    {
        "id": 2,
        "name": "服装",
        "parent_id": 0,
        "level": 1
    }
]
优缺点
  • 优点:逻辑简单,易于理解,适合中小型数据量(分类层级 < 1000);
  • 缺点:递归过深时可能导致栈溢出(如分类层级 > 1000),且需要一次性加载所有分类数据,内存占用较高。

方法2:迭代法(非递归构建树形结构)

思路
  1. 先查询所有分类数据并按 parent_id 分组;
  2. 从顶级分类(parent_id = 0)开始,逐层构建树形结构;
  3. 使用循环代替递归,避免栈溢出风险。
代码实现
<?php
/**
 * 迭代构建无限分类树
 * @param array $categories 所有分类数据
 * @return array 树形结构分类
 */
function buildTreeIterative(array $categories): array
{
    // 按 parent_id 分组
    $grouped = [];
    foreach ($categories as $category) {
        $grouped[$category['parent_id']][] = $

标签: #php #无限分类