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;

在实际开发中,选择使用哪种方式实现无极限分类,需要根据实际情况和性能要求进行选择。

以上就是无极限分类的存取方法,希望对你有所帮助。