php无极限分类怎么存取
时间 : 2023-03-25 12:38:01声明: : 文章内容来自网络,不保证准确性,请自行甄别信息有效性
无极限分类是一种常用的数据存储方式,常见于电商平台的商品分类、新闻网站的新闻分类等业务场景中。
在 PHP 中实现无极限分类主要有两种方式:嵌套集合模型和递归模型。其中,嵌套集合模型是一种非常高效的存取方式,但是实现起来比较复杂,而递归模型则比较简单易懂,但是效率较低。下面依次介绍这两种方式的实现方法。
1. 嵌套集合模型
嵌套集合模型是一种树形结构,每个节点都有左右值。如果一个节点的左值小于它的右值,那么我们可以认为它是树上的一个子树。具体实现方式如下:
创建一张表格,命名为 `categories`,包含以下字段:
id INT(11) PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
parent_id INT(11) NOT NULL DEFAULT '0',
lft INT(11) NOT NULL,
rgt INT(11) NOT NULL
其中,`name` 表示分类名称,`parent_id` 表示父分类的 ID,`lft` 和 `rgt` 分别表示左值和右值。
接下来,我们可以通过以下代码来存储分类:
function insert_category($name, $parent_id = 0) {
global $pdo;
// 获取父分类的右值
$sql = "SELECT rgt FROM categories WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$parent_id]);
$parent = $stmt->fetch(PDO::FETCH_ASSOC);
// 插入新的分类
$sql = "UPDATE categories SET rgt = rgt + 2 WHERE rgt > ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$parent['rgt']]);
$sql = "UPDATE categories SET lft = lft + 2 WHERE lft > ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$parent['rgt']]);
$sql = "INSERT INTO categories (name, parent_id, lft, rgt) VALUES (?, ?, ?, ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute([$name, $parent_id, $parent['rgt'], $parent['rgt'] + 1]);
return $pdo->lastInsertId();
}
该函数接收两个参数,分别是分类名称和父分类的 ID,若该分类是根分类,则默认父分类的 ID 为 0。
通过该函数生成的分类树是一棵多叉树,查询子分类会比较麻烦。查询一级子分类的代码如下:
function get_sub_categories($parent_id) {
global $pdo;
$sql = "SELECT * FROM categories WHERE parent_id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$parent_id]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
该函数接收一个参数,即父分类的 ID,返回其子分类的数组。查询所有子孙分类的函数需要用递归来实现,代码如下:
function get_all_sub_categories($parent_id) {
global $pdo;
$sql = "SELECT * FROM categories WHERE lft > (SELECT lft FROM categories WHERE id = ?) AND rgt < (SELECT rgt FROM categories WHERE id = ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute([$parent_id, $parent_id]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
该函数接收一个参数,即父分类的 ID,返回其所有子孙分类的数组。该函数使用了一个子查询来获取指定分类的左值和右值。
2. 递归模型
递归模型是一种基于递归的树形结构,每个节点都包含一个 ID 和一个父节点 ID。具体实现方式如下:
创建一张表格,命名为 `categories`,包含以下字段:
id INT(11) PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
parent_id INT(11) NOT NULL DEFAULT '0'
其中,`name` 表示分类名称,`parent_id` 表示父分类的 ID。
接下来,我们可以通过以下代码来存储分类:
function insert_category($name, $parent_id = 0) {
global $pdo;
$sql = "INSERT INTO categories (name, parent_id) VALUES (?, ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute([$name, $parent_id]);
return $pdo->lastInsertId();
}
该函数接收两个参数,分别是分类名称和父分类的 ID,若该分类是根分类,则默认父分类的 ID 为 0。
查询子分类的代码比较简单,如下所示:
function get_sub_categories($parent_id) {
global $pdo;
$sql = "SELECT * FROM categories WHERE parent_id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$parent_id]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
该函数接收一个参数,即父分类的 ID,返回其子分类的数组。查询所有子孙分类的函数需要用递归来实现,代码如下:
function get_all_sub_categories($parent_id) {
global $pdo;
$sql = "SELECT * FROM categories WHERE parent_id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$parent_id]);
$sub_categories = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($sub_categories as &$sub_category) {
$sub_category['sub_categories'] = get_all_sub_categories($sub_category['id']);
}
return $sub_categories;
}
该函数接收一个参数,即父分类的 ID,返回其所有子孙分类的数组。该函数使用了递归来获取子分类的子分类的数组。每个子分类会包含一个 `sub_categories` 键,对应其子分类的数组。
以上是 PHP 实现无极限分类的两种方法,开发者可以根据实际需求选择适合自己的存取方式。
无极限分类是指一种数据存储方式,用于存储树形结构的数据,主要用于文章分类、商品分类等场景。PHP提供了几种实现无极限分类的方法,其中比较常用的有两种:嵌套集合模型和闭包表模型。
1. 嵌套集合模型
嵌套集合模型是一种将树形结构存储在数据库表中的方式,它的核心是通过左右值(lft和rgt)来表示每个节点在树中的位置。具体实现方式如下:
- 数据库表结构
我们可以创建一个名为categories的表,包含以下字段:
id: 分类ID
name: 分类名称
parent_id: 父分类ID
lft: 左值
rgt: 右值
- 存储数据
当向categories表中添加新的分类数据时,需要计算该分类在树中的左值和右值,并同时更新所有与该节点相关的左值和右值。具体实现方式如下:
1) 获取父分类的右值
SELECT rgt FROM categories WHERE id = parent_id;
2) 将所有右值大于等于该值的节点右值加2
UPDATE categories SET rgt = rgt + 2 WHERE rgt >= parent_rgt;
3) 将所有左值大于等于该值的节点左值加2
UPDATE categories SET lft = lft + 2 WHERE lft >= parent_rgt;
4) 将该节点的左值设置为父分类的右值
lft = parent_rgt
5) 将该节点的右值设置为左值+1
rgt=lft+1
6) 将新的分类数据插入到categories表中
- 加载数据
当需要获取一棵无极限树时,只需要查询包含该节点的左值和右值范围内的所有节点即可。具体实现方式如下:
SELECT * FROM categories WHERE lft >= $left AND rgt <= $right;
2. 闭包表模型
闭包表模型是一种将树形结构存储在两个表中的方式,包含下面两张表:
- categories表
id: 分类ID
name: 分类名称
parent_id: 父分类ID
- closure表
ancestor: 祖先ID
descendant: 后代ID
depth: 距离
- 存储数据
当向categories表中添加新的分类数据时,需要同时在closure表中添加该分类与自身的关系,以及该分类与所有祖先分类的关系。具体实现方式如下:
1) 插入分类数据
INSERT INTO categories (name, parent_id) VALUES ($name, $parent_id);
2) 获取新的分类ID
SELECT LAST_INSERT_ID();
3) 向closure表中插入自身关系
INSERT INTO closure (ancestor, descendant, depth) VALUES ($new_id, $new_id, 0);
4) 向closure表中插入祖先关系
INSERT INTO closure (ancestor, descendant, depth)
SELECT ancestor, $new_id, depth+1 FROM closure WHERE descendant = $parent_id;
INSERT INTO closure (ancestor, descendant, depth)
SELECT $new_id, ancestor, depth+1 FROM closure WHERE descendant = $parent_id;
- 加载数据
使用闭包表模型加载数据时,需要先查询出当前分类的所有后代分类,然后根据后代分类的深度级别选择分类的缩进位置。具体实现方式如下:
SELECT c.*, COUNT(p.ancestor) - 1 AS level
FROM categories AS c
JOIN closure AS p ON p.descendant = c.id OR p.ancestor = c.id
GROUP BY c.id
ORDER BY p.depth ASC, c.name ASC;
在实际开发中,选择使用哪种方式实现无极限分类,需要根据实际情况和性能要求进行选择。
以上就是无极限分类的存取方法,希望对你有所帮助。
上一篇
1加到10php怎么写
下一篇
php怎么把时分秒去掉
https/SSL证书广告优选IDC>>
推荐主题模板更多>>
推荐文章