php无限分类的实现
无限分类的实现方法
无限分类通常用于构建多层级结构,如商品分类、菜单管理等。以下是几种常见的实现方式:
递归方法实现
使用递归函数遍历分类树结构:
function getCategoryTree($parent_id = 0, $level = 0) {
$categories = [];
$result = db_query("SELECT * FROM categories WHERE parent_id = $parent_id");
while ($row = db_fetch_array($result)) {
$row['level'] = $level;
$categories[] = $row;
$categories = array_merge($categories, getCategoryTree($row['id'], $level + 1));
}
return $categories;
}
闭包表(Closure Table)设计
闭包表是一种高效的无限分类存储方案:
CREATE TABLE categories (
id INT PRIMARY KEY,
name VARCHAR(255)
);
CREATE TABLE category_paths (
ancestor INT,
descendant INT,
depth INT,
PRIMARY KEY (ancestor, descendant)
);
查询所有子分类:

function getDescendants($category_id) {
$query = "SELECT c.* FROM categories c
JOIN category_paths cp ON c.id = cp.descendant
WHERE cp.ancestor = $category_id AND cp.depth > 0";
return db_query($query);
}
预排序遍历树算法(MPTT)
MPTT通过左右值标记节点位置:
CREATE TABLE categories (
id INT PRIMARY KEY,
name VARCHAR(255),
lft INT,
rgt INT
);
获取子树:
function getSubTree($node_id) {
$node = db_query("SELECT lft, rgt FROM categories WHERE id = $node_id");
$query = "SELECT * FROM categories
WHERE lft BETWEEN {$node['lft']} AND {$node['rgt']}
ORDER BY lft";
return db_query($query);
}
扁平化存储+路径枚举
使用path字段存储完整路径:

CREATE TABLE categories (
id INT PRIMARY KEY,
name VARCHAR(255),
path VARCHAR(255) -- 如 '1,5,12' 表示1→5→12的路径
);
查询子分类:
function getChildren($category_id) {
return db_query("SELECT * FROM categories WHERE path LIKE '%,$category_id,%'");
}
使用嵌套集合模型
嵌套集合模型与MPTT类似,但实现方式不同:
function rebuildTree($parent_id = 0, $left = 1) {
$right = $left + 1;
$result = db_query("SELECT id FROM categories WHERE parent_id = $parent_id");
while ($row = db_fetch_array($result)) {
$right = rebuildTree($row['id'], $right);
}
db_query("UPDATE categories SET lft = $left, rgt = $right WHERE id = $parent_id");
return $right + 1;
}
选择哪种方法取决于具体需求:
- 递归方法简单但效率较低
- 闭包表和MPTT查询效率高但写操作复杂
- 路径枚举简单直观但路径管理需要额外逻辑
实际应用中,闭包表或MPTT通常是最佳选择,特别是当分类层级较深且需要频繁查询时。






