递归查询所有分类并以树形结构方式展示

<?php
/**
 * 递归查询所有分类并以树形结构方式展示
 *
 * ========================= 建立测试表及测试数据·开始 =========================
 *
 * CREATE TABLE `category` (
 *   `cid` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '分类ID(自增主键)',
 *   `cname` varchar(64) NOT NULL DEFAULT '' COMMENT '分类名称',
 *   `parent_cid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '父级分类ID',
 *   PRIMARY KEY (`cid`)
 * ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分类信息表';
 *
 * INSERT INTO `category` VALUES ('1', '湖北省', '0');
 * INSERT INTO `category` VALUES ('2', '湖南省', '0');
 * INSERT INTO `category` VALUES ('3', '广东省', '0');
 * INSERT INTO `category` VALUES ('4', '广西省', '0');
 * INSERT INTO `category` VALUES ('5', '江西省', '0');
 * INSERT INTO `category` VALUES ('6', '深圳市', '3');
 * INSERT INTO `category` VALUES ('7', '东莞市', '3');
 * INSERT INTO `category` VALUES ('8', '广州市', '3');
 * INSERT INTO `category` VALUES ('9', '佛山市', '3');
 * INSERT INTO `category` VALUES ('10', '珠海市', '3');
 * INSERT INTO `category` VALUES ('11', '越秀区', '8');
 * INSERT INTO `category` VALUES ('12', '白云区', '8');
 * INSERT INTO `category` VALUES ('13', '天河区', '8');
 * INSERT INTO `category` VALUES ('14', '海珠区', '8');
 * INSERT INTO `category` VALUES ('15', '黄埔区', '8');
 *
 * ========================= 建立测试表及测试数据·结束 =========================
 *
 */

/**
 * 获取PDO实例
 *
 * @return object PDO实例
 */
function get_pdo()
{
    global $pdo;

    if ($pdo === null) {
        $type     = 'mysql';     // 数据库类型
        $host     = 'localhost'; // 主机地址
        $dbname   = 'dbname';    // 数据库名
        $port     = 3306;        // 服务端口号
        $charset  = 'utf8mb4';   // 字符编码
        $username = 'manong';    // 账号
        $password = '*********'; // 密码

        $options = array(
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES {$charset}",
            PDO::ATTR_EMULATE_PREPARES => false, // 禁用PHP模拟预处理(把预处理工作交给MySQL服务端)
        );

        $dsn = "{$type}:host={$host};dbname={$dbname};port={$port};charset={$charset};";


        $pdo = new PDO($dsn, $username, $password, $options);
    }

    return $pdo;
}

/**
 * 获取所有分类的数据(树形结构)
 *
 * @param int $parent_cid 父级分类ID
 * @return array 所有分类的数据(树形结构)
 */
function get_data($parent_cid = 0)
{
    $pdo = get_pdo();

    $data = array();

    // 核心是使用parent_cid作为查询条件,再结合递归就可以实现以树形结构查出所有分类
    $sql = "SELECT * FROM `category` WHERE `parent_cid` = :parent_cid;";

    $sth = $pdo->prepare($sql);
    $sth->bindParam(':parent_cid', $parent_cid);
    $sth->execute();
    $data = $sth->fetchAll();

    foreach ($data as $key => $value) {
        $data[$key]['sub'] = get_data($value['cid']); // 递归查询子分类
    }

    return $data;
}

/**
 * 以树形结构方式展示所有分类
 *
 * @param array $data 分类数据
 * @param int $level 分类数据的层级
 * @return void
 */
function display_tree($data, $level = 0)
{
    foreach ($data as $key => $value) {
        $prefix = str_repeat('|----', $level);
        echo "{$prefix}{$value['cname']}<br>" . PHP_EOL;

        // 检查是否有子类,如果有则继续递归输出
        if (isset($value['sub']) && count($value['sub'])) {
            display_tree($value['sub'], $level + 1);
        }
    }
}

$data = get_data();
display_tree($data);
/**
 *
 * ========================= 输出结果·开始 =========================
 *
 * 湖北省
 * 湖南省
 * 广东省
 * |----深圳市
 * |----东莞市
 * |----广州市
 * |----|----越秀区
 * |----|----白云区
 * |----|----天河区
 * |----|----海珠区
 * |----|----黄埔区
 * |----佛山市
 * |----珠海市
 * 广西省
 * 江西省
 *
 * ========================= 输出结果·结束 =========================
 *
 */

Copyright © 2024 码农人生. All Rights Reserved