PHP实现简单的无限极分类

原创 阁主  2026-03-26 06:25:44  阅读 6516 次 评论 0 条
摘要:

学有所感,简单记录一下使用PHP实现简单的无限极分类。

效果

效果很简单就是直接用ul和li输出,更直观的看到层级现象。

简单的输出示例图

简单原理介绍

首先呢,数据表(cates)的大致内容在下面,主要起作用的就是pid属性,能够明确指向上级的id。

数据表cates

接着就是最朴素的描述不如更直观的图示解说,如上所说的pid作用最大,下图就是明确指向上级分类的id。(下图是pid=0才是一级ID,途中表述不太明确。)

再接着就是更直观的解决方案就是把整个子集分类放到上级的数组(child)里,这个child键是需要我们自己去创建的;如果一个分类都只有子集分类,那么这个child里将是一维数组,如果其子集有下级分类,那么就会是二维数组,甚至N维数组。一般常规分类也直到三级足够用了。

SQL代码

下面是数据表的所有sql,导出给各位道友学习,直接导入数据库就行。

/*
 Navicat Premium Data Transfer

 Source Server         : EVE
 Source Server Type    : MySQL
 Source Server Version : 80020 (8.0.20)
 Source Host           : localhost:3306
 Source Schema         : guer

 Target Server Type    : MySQL
 Target Server Version : 80020 (8.0.20)
 File Encoding         : 65001

 Date: 22/08/2023 17:07:21
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for cates
-- ----------------------------
DROP TABLE IF EXISTS `cates`;
CREATE TABLE `cates`  (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `pid` int NULL DEFAULT NULL,
  `status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of cates
-- ----------------------------
INSERT INTO `cates` VALUES (1, '半身裙', 2, '1');
INSERT INTO `cates` VALUES (2, '裙子', 3, '1');
INSERT INTO `cates` VALUES (3, '衣服', 0, '1');
INSERT INTO `cates` VALUES (4, '连衣裙', 2, '1');
INSERT INTO `cates` VALUES (5, '电子产品', 0, '1');
INSERT INTO `cates` VALUES (6, '手机', 5, '1');
INSERT INTO `cates` VALUES (7, '笔记本', 5, '1');
INSERT INTO `cates` VALUES (8, '电视机', 5, '1');

SET FOREIGN_KEY_CHECKS = 1;

PHP代码实现

示例的代码有点繁杂,实现功能为主,各位道友有能力的可以自行修改展示方法。

// 连接数据库并查询数据
$db = new PDO('mysql:host=localhost;dbname=guer', 'root', 'root');
$RES = $db->query('select `id`,`pid`,`name` from `cates` where `status`=1 ;')->fetchAll(PDO::FETCH_ASSOC);
printf('<pre>%s</pre>', print_r($RES, true));

# 递归函数,筛选pid==0的数据为第一层,然后再递归pid==上级的pid筛选子集,直到没有子集为止
function ruleLayer($rule, $pid = 0)
{
    $arr = [];
    foreach ($rule as $v) {
        if ($v['pid'] == $pid) {
            # chile 是存放子集的数组,条件是pid==上级的id
            $v['child'] = ruleLayer($rule, $v['id']);
            $arr[] = $v;
        }
    }
    return $arr;
}

echo '<hr>';
$result = ruleLayer($RES);
printf('<pre>%s</pre>', print_r($result, true));

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <ul class="first">
        <?php foreach ($result as $v) : extract($v) ?>
            <li>
                <?= $name ?>
                <ul class="second">
                    <?php if (!empty($child)) :
                        foreach ($child as $v1) : extract($v1) ?>

                            <li>
                                <?= $name ?>
                                <ul>
                                    <?php if (!empty($child)) :
                                        foreach ($child as $v2) : extract($v2) ?>
                                            <li>
                                                <?= $name ?>
                                                <ul>
                                                    <?php if (!empty($child)) :
                                                        foreach ($child as $v3) : extract($v3) ?>
                                                            <li>
                                                                <?= $name ?>

                                                            </li>
                                                    <?php endforeach;
                                                    endif ?>
                                                </ul>
                                            </li>
                                    <?php endforeach;
                                    endif ?>
                                </ul>
                            </li>
                    <?php endforeach;
                    endif ?>

                </ul>
            </li>
        <?php endforeach ?>
    </ul>
</body>

</html>

改造为JSON

甚至你还可以直接把遍历好的分类数组直接转成json的格式,在你的项目有前后端分离的情况下,由前端渲染出去。这边只给返回json的示例,就不给前端渲染的示例了。其实跟上面小示例差不多,完整的PHP部分代码在下面:

// 连接数据库并查询数据
$db = new PDO('mysql:host=localhost;dbname=guer', 'root', 'root');
$RES = $db->query('select `id`,`pid`,`name` from `cates` where `status`=1 ;')->fetchAll(PDO::FETCH_ASSOC);
// printf('<pre>%s</pre>', print_r($RES, true));


# 递归函数,筛选pid==0的数据为第一层,然后再递归pid==上级的pid筛选子集,直到没有子集为止
function ruleLayer($rule, $pid = 0)
{
    $arr = [];
    foreach ($rule as $v) {
        if ($v['pid'] == $pid) {
            # chile 是存放子集的数组,条件是pid==上级的id
            $v['child'] = ruleLayer($rule, $v['id']);
            $arr[] = $v;
        }
    }
    return $arr;
}

$result = ruleLayer($RES);
echo json_encode($result, 320);

返回前端的json效果图,由于一页展示不完,分两张图:

本文地址:https://www.mainblog.cn/336.html
版权声明:本文为原创文章,版权归 阁主 所有,欢迎分享本文,转载请保留出处!
免责申明:有些内容源于网络,没能联系到作者。如侵犯到你的权益请告知,我们会尽快删除相关内容。
NEXT:已经是最新一篇了

评论已关闭!