php 怎么进行无限级查询

fiy 其他 185

回复

共3条回复 我来回复
  • worktile的头像
    worktile
    Worktile官方账号
    评论

    在PHP中进行无限级查询可以使用递归方法。下面是一个简单的示例代码:

    “`php
    connect_error) {
    die(“连接失败: ” . $conn->connect_error);
    }

    // 定义一个递归函数来进行无限级查询
    function getCategory($parent_id, $conn, $level = 0) {
    // 构建查询语句
    $sql = “SELECT * FROM categories WHERE parent_id = $parent_id”;

    // 执行查询
    $result = $conn->query($sql);

    // 检查查询结果是否为空
    if ($result->num_rows > 0) {
    // 输出查询结果
    while($row = $result->fetch_assoc()) {
    echo str_repeat(‘-‘, $level) . $row[‘name’] . “
    “;
    // 递归调用自身查询子分类
    getCategory($row[‘id’], $conn, $level + 1);
    }
    }
    }

    // 调用递归函数查询顶级分类
    getCategory(0, $conn);

    // 关闭数据库连接
    $conn->close();
    ?>
    “`

    以上示例代码实现了一个基本的无限级分类查询。首先定义了数据库连接信息,然后与数据库建立连接。接着定义了一个递归函数 getCategory 来进行查询。该函数首先构建查询语句,然后执行查询并将查询结果输出。在函数内部,通过递归调用自身来查询子分类,同时通过增加一个 level 参数来控制缩进显示层级关系。最后,调用该递归函数并传入顶级分类的 parent_id(通常为0)来开始查询。

    请根据自己的数据库表结构和需求进行相应的修改。

    2年前 0条评论
  • fiy的头像
    fiy
    Worktile&PingCode市场小伙伴
    评论

    在PHP中,要进行无限级查询,可以使用递归方法来实现。以下是实现无限级查询的步骤:

    步骤1:准备数据
    首先,需要准备一张数据表来存储无限级分类的数据。表中至少需要包含两个字段,一个是主键字段,用来唯一标识每个分类;另一个是父级分类的ID,用来标识当前分类的父级分类。可以在数据库中创建一个名为”categories”的表,如下所示:

    CREATE TABLE categories (
    id INT AUTO_INCREMENT PRIMARY KEY,
    parent_id INT,
    name VARCHAR(255)
    );

    步骤2:插入数据
    在数据表中插入一些分类数据,用于测试。可以使用如下的SQL语句:

    INSERT INTO categories (parent_id, name)
    VALUES (NULL, ‘分类1’),
    (1, ‘分类2’),
    (1, ‘分类3’),
    (2, ‘分类4’),
    (2, ‘分类5’),
    (3, ‘分类6’);

    步骤3:创建递归函数
    在PHP代码中,创建一个递归函数来查询无限级分类的数据。函数可以接受一个参数,表示当前分类的父级分类ID。在函数内部,先查询当前分类的子级分类,然后再递归调用自身,查询子级分类的子级分类,以此类推。函数的代码如下所示:

    function getCategories($parentId = NULL) {
    $sql = “SELECT * FROM categories WHERE parent_id = :parentId”;
    $stmt = $pdo->prepare($sql);
    $stmt->bindValue(‘:parentId’, $parentId, PDO::PARAM_INT);
    $stmt->execute();
    $categories = $stmt->fetchAll();

    $result = [];
    foreach ($categories as $category) {
    $children = getCategories($category[‘id’]);
    $category[‘children’] = $children;
    $result[] = $category;
    }

    return $result;
    }

    步骤4:测试函数
    调用上述创建的函数,测试无限级查询的功能。可以使用如下的代码:

    $categories = getCategories();
    var_dump($categories);

    运行代码后,可以看到输出的结果是一个多维数组,包含了所有的分类信息及其子级分类信息。可以根据需要对查询结果进行处理,展示在网页上或者其他地方。

    上述是在PHP中进行无限级查询的基本步骤。根据实际需求,可能需要对查询结果进行排序、分页等操作。

    2年前 0条评论
  • 不及物动词的头像
    不及物动词
    这个人很懒,什么都没有留下~
    评论

    PHP无限级查询可以使用数据库中的递归关系来实现。在数据库设计中,通常使用两种方法来实现无限级查询:嵌套集合模型和闭包表模型。本文将详细讲解这两种方法的操作流程和使用方式。

    ## 一、嵌套集合模型

    ### 1. 数据库表设计

    在使用嵌套集合模型实现无限级查询时,首先需要设计数据库表。常见的表设计如下:

    “`sql
    CREATE TABLE categories (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    lft INT NOT NULL,
    rgt INT NOT NULL
    );
    “`

    其中,`id`字段是分类的唯一标识,`name`字段是分类的名称,`lft`字段和`rgt`字段用于表示分类在树状结构中的左边界和右边界。具体的表数据可以根据实际需求进行插入。

    ### 2. 添加分类

    使用PHP操作数据库,可以使用`PDO`扩展或者其他数据库操作类库来实现。具体的操作流程如下:

    “`php
    beginTransaction();

    // 查询父级分类信息
    if ($parent_id) {
    $stmt = $dbh->prepare(‘SELECT * FROM categories WHERE id = :parent_id’);
    $stmt->bindParam(‘:parent_id’, $parent_id);
    $stmt->execute();
    $parent_category = $stmt->fetch(PDO::FETCH_ASSOC);

    // 更新右边界
    $stmt = $dbh->prepare(‘UPDATE categories SET rgt = rgt + 2 WHERE rgt >= :parent_rgt’);
    $stmt->bindParam(‘:parent_rgt’, $parent_category[‘rgt’]);
    $stmt->execute();

    // 更新左边界
    $stmt = $dbh->prepare(‘UPDATE categories SET lft = lft + 2 WHERE lft > :parent_rgt’);
    $stmt->bindParam(‘:parent_rgt’, $parent_category[‘rgt’]);
    $stmt->execute();

    $left = $parent_category[‘rgt’];
    $right = $parent_category[‘rgt’] + 1;
    } else {
    // 查询最大右边界
    $stmt = $dbh->prepare(‘SELECT MAX(rgt) as max_rgt FROM categories’);
    $stmt->execute();
    $result = $stmt->fetch(PDO::FETCH_ASSOC);
    $left = $result[‘max_rgt’] + 1;
    $right = $result[‘max_rgt’] + 2;
    }

    // 添加分类
    $stmt = $dbh->prepare(‘INSERT INTO categories (name, lft, rgt) VALUES (:name, :left, :right)’);
    $stmt->bindParam(‘:name’, $name);
    $stmt->bindParam(‘:left’, $left);
    $stmt->bindParam(‘:right’, $right);
    $stmt->execute();

    // 提交事务
    $dbh->commit();
    }
    “`

    上述代码中的`addCategory`函数用于添加分类,其中`parent_id`参数表示父级分类的ID,默认为`null`,表示根分类。函数首先会查询父级分类的信息,然后根据父级分类的右边界来更新其他分类的左右边界,在新增分类时同时更新左边界和右边界。具体操作都是使用MySQL的更新语句完成的。最后通过事务的方式来保证数据的一致性。

    ### 3. 查询分类

    查询分类的过程就是根据嵌套集合模型的左右边界进行查询。可以使用递归的方式来实现查询所有子分类的功能。具体的操作流程如下:

    “`php
    prepare(‘SELECT * FROM categories WHERE lft > :left AND rgt < :right'); $stmt->bindParam(‘:left’, $left);
    $stmt->bindParam(‘:right’, $right);
    $stmt->execute();
    $categories = $stmt->fetchAll(PDO::FETCH_ASSOC);

    foreach ($categories as &$category) {
    $category[‘name’] = str_repeat(‘-‘, $depth) . $category[‘name’];
    $category[‘children’] = getCategories($category[‘id’], $depth + 1);
    }

    return $categories;
    }
    “`

    上述代码中的`getCategories`函数接收两个参数,`parent_id`表示要查询的父级分类的ID,默认为`null`,表示根分类;`depth`表示当前分类的层级深度,默认为0。函数首先根据父级分类的左右边界查询子分类,然后使用递归的方式查询每个子分类的子分类,并将结果保存在每个分类的`children`字段中。同时根据分类的深度调整分类的名称,在名称前加上相应数量的横线。

    ### 4. 更新分类

    更新分类的操作流程和添加分类类似,只是需要调整左右边界的值。具体的操作流程如下:

    “`php
    prepare(‘SELECT * FROM categories WHERE id = :id’);
    $stmt->bindParam(‘:id’, $id);
    $stmt->execute();
    $category = $stmt->fetch(PDO::FETCH_ASSOC);

    // 更新分类名称
    $stmt = $dbh->prepare(‘UPDATE categories SET name = :name WHERE id = :id’);
    $stmt->bindParam(‘:name’, $name);
    $stmt->bindParam(‘:id’, $id);
    $stmt->execute();

    // 计算需要增加或减少的值
    $diff = strlen($name) – strlen($category[‘name’]);

    // 更新子分类的左右边界
    $stmt = $dbh->prepare(‘UPDATE categories SET lft = lft + :diff, rgt = rgt + :diff WHERE lft > :left AND rgt < :right'); $stmt->bindParam(‘:diff’, $diff);
    $stmt->bindParam(‘:left’, $category[‘lft’]);
    $stmt->bindParam(‘:right’, $category[‘rgt’]);
    $stmt->execute();
    }
    “`

    上述代码中的`updateCategory`函数用于更新分类的名称。函数首先查询分类的原始名称,然后更新分类的名称,最后根据分类名称的增加或减少来调整子分类的左右边界。

    ### 5. 删除分类

    删除分类的操作流程也与添加分类类似,需要调整左右边界的值。具体的操作流程如下:

    “`php
    prepare(‘SELECT * FROM categories WHERE id = :id’);
    $stmt->bindParam(‘:id’, $id);
    $stmt->execute();
    $category = $stmt->fetch(PDO::FETCH_ASSOC);

    // 开启事务
    $dbh->beginTransaction();

    // 删除分类及其所有子分类
    $stmt = $dbh->prepare(‘DELETE FROM categories WHERE lft >= :left AND rgt <= :right'); $stmt->bindParam(‘:left’, $category[‘lft’]);
    $stmt->bindParam(‘:right’, $category[‘rgt’]);
    $stmt->execute();

    // 更新左右边界
    $diff = $category[‘rgt’] – $category[‘lft’] + 1;
    $stmt = $dbh->prepare(‘UPDATE categories SET lft = lft – :diff WHERE lft > :right’);
    $stmt->bindParam(‘:diff’, $diff);
    $stmt->bindParam(‘:right’, $category[‘rgt’]);
    $stmt->execute();

    $stmt = $dbh->prepare(‘UPDATE categories SET rgt = rgt – :diff WHERE rgt > :right’);
    $stmt->bindParam(‘:diff’, $diff);
    $stmt->bindParam(‘:right’, $category[‘rgt’]);
    $stmt->execute();

    // 提交事务
    $dbh->commit();
    }
    “`

    上述代码中的`deleteCategory`函数用于删除分类。函数首先查询分类的信息,然后通过事务的方式删除分类及其所有子分类,在删除分类后需要调整左右边界的值,具体操作与添加分类和更新分类类似。

    ## 二、闭包表模型

    ### 1. 数据库表设计

    闭包表模型是另一种实现无限级查询的方法。在使用闭包表模型时,需要添加一张额外的表来保存分类之间的关系。常见的表设计如下:

    “`sql
    CREATE TABLE categories (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL
    );

    CREATE TABLE categories_closure (
    ancestor_id INT NOT NULL,
    descendant_id INT NOT NULL,
    depth INT NOT NULL,
    PRIMARY KEY (ancestor_id, descendant_id)
    );
    “`

    其中,`categories`表用于保存分类的基本信息,`categories_closure`表用于保存分类之间的关系。具体的表数据可以根据实际需求进行插入。

    ### 2. 添加分类

    使用PHP操作数据库,可以使用`PDO`扩展或者其他数据库操作类库来实现。具体的操作流程如下:

    “`php
    beginTransaction();

    if ($parent_id) {
    // 查询父级分类的祖先分类
    $stmt = $dbh->prepare(‘SELECT ancestor_id FROM categories_closure WHERE descendant_id = :parent_id’);
    $stmt->bindParam(‘:parent_id’, $parent_id);
    $stmt->execute();
    $ancestors = $stmt->fetchAll(PDO::FETCH_COLUMN);

    // 添加分类关系
    $stmt = $dbh->prepare(‘INSERT INTO categories_closure (ancestor_id, descendant_id, depth) VALUES (:ancestor_id, :descendant_id, :depth)’);
    foreach ($ancestors as $ancestor_id) {
    $stmt->bindValue(‘:ancestor_id’, $ancestor_id);
    $stmt->bindValue(‘:descendant_id’, $category_id);
    $stmt->bindValue(‘:depth’, count(explode(‘,’, $ancestors)) + 1);
    $stmt->execute();
    }

    // 添加分类关系(自身和父级分类)
    $stmt = $dbh->prepare(‘INSERT INTO categories_closure (ancestor_id, descendant_id, depth) VALUES (:category_id, :category_id, 0), (:parent_id, :category_id, 1)’);
    $stmt->bindParam(‘:category_id’, $category_id);
    $stmt->bindParam(‘:parent_id’, $parent_id);
    $stmt->execute();
    } else {
    // 添加顶级分类
    $stmt = $dbh->prepare(‘INSERT INTO categories_closure (ancestor_id, descendant_id, depth) VALUES (:category_id, :category_id, 0)’);
    $stmt->bindParam(‘:category_id’, $category_id);
    $stmt->execute();
    }

    // 添加分类
    $stmt = $dbh->prepare(‘INSERT INTO categories (name) VALUES (:name)’);
    $stmt->bindParam(‘:name’, $name);
    $stmt->execute();

    // 提交事务
    $dbh->commit();
    }
    “`

    上述代码中的`addCategory`函数用于添加分类。函数首先查询父级分类的祖先分类,然后在分类关系表中添加分类之间的关系,其中祖先分类的深度是根据祖先分类的个数来确定的。最后在分类关系表中同时添加分类和父级分类的关系。具体操作都是使用MySQL的插入语句完成的。最后通过事务的方式来保证数据的一致性。

    ### 3. 查询分类

    查询分类的过程就是根据分类之间的关系进行查询。可以使用递归的方式来实现查询每个分类的子分类的功能。具体的操作流程如下:

    “`php
    prepare($sql);
    $stmt->bindParam(‘:ancestor_id’, $parent_id);
    $stmt->bindParam(‘:depth’, $depth + 1);
    $stmt->execute();
    $categories = $stmt->fetchAll(PDO::FETCH_ASSOC);

    foreach ($categories as &$category) {
    $category[‘name’] = str_repeat(‘-‘, $depth) . $category[‘name’];
    $category[‘children’] = getCategories($category[‘id’], $depth + 1);
    }

    return $categories;
    }
    “`

    上述代码中的`getCategories`函数接收两个参数,`parent_id`表示要查询的父级分类的ID,默认为`null`,表示所有顶级分类;`depth`表示当前分类的层级深度,默认为0。函数首先根据分类之间的关系查询子分类,然后使用递归的方式查询每个子分类的子分类,并将结果保存在每个分类的`children`字段中。同时根据分类的深度调整分类的名称,在名称前加上相应数量的横线。

    ### 4. 更新分类

    更新分类的操作流程和添加分类类似,只是需要调整分类之间的关系。具体的操作流程如下:

    “`php
    prepare(‘SELECT * FROM categories WHERE id = :id’);
    $stmt->bindParam(‘:id’, $id);
    $stmt->execute();
    $category = $stmt->fetch(PDO::FETCH_ASSOC);

    // 更新分类名称
    $stmt = $dbh->prepare(‘UPDATE categories SET name = :name WHERE id = :id’);
    $stmt->bindParam(‘:name’, $name);
    $stmt->bindParam(‘:id’, $id);
    $stmt->execute();

    // 更新分类关系
    $stmt = $dbh->prepare(‘UPDATE categories_closure SET depth = depth + :diff WHERE ancestor_id = :id’);

    // 查询分类的子分类
    $stmt = $dbh->prepare(‘SELECT descendant_id FROM categories_closure WHERE ancestor_id = :id AND depth > 0’);
    $stmt->bindParam(‘:id’, $id);
    $stmt->execute();
    $descendants = $stmt->fetchAll(PDO::FETCH_COLUMN);

    // 更新子分类的深度
    $stmt = $dbh->prepare(‘UPDATE categories_closure SET depth = depth + :diff WHERE descendant_id = :descendant_id’);
    foreach ($descendants as $descendant_id) {
    $stmt->bindValue(‘:diff’, substr_count($category[‘name’], ‘-‘) – substr_count($name, ‘-‘));
    $stmt->bindValue(‘:descendant_id’, $descendant_id);
    $stmt->execute();
    }
    }
    “`

    上述代码中的`updateCategory`函数用于更新分类的名称。函数首先查询分类的原始名称,然后更新分类的名称,最后根据分类名称的增加或减少来调整子分类的深度。

    ### 5. 删除分类

    删除分类的操作流程也与添加分类类似,需要删除分类之间的关系。具体的操作流程如下:

    “`php
    prepare(‘SELECT descendant_id FROM categories_closure WHERE ancestor_id = :id’);
    $stmt->bindParam(‘:id’, $id);
    $stmt->execute();
    $descendants = $stmt->fetchAll(PDO::FETCH_COLUMN);

    // 开启事务
    $dbh->beginTransaction();

    // 删除分类关系
    $stmt = $dbh->prepare(‘DELETE FROM categories_closure WHERE ancestor_id = :id OR descendant_id = :id’);
    $stmt->bindParam(‘:id’, $id);
    $stmt->execute();

    // 更新分类关系
    $stmt = $dbh->prepare(‘UPDATE categories_closure SET depth = depth – 1 WHERE ancestor_id IN (‘ . implode(‘,’, $descendants) . ‘)’);
    $stmt->execute();

    // 删除分类
    $stmt = $dbh->prepare(‘DELETE FROM categories WHERE id = :id’);
    $stmt->bindParam(‘:id’, $id);
    $stmt->execute();

    2年前 0条评论
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部