实现PHP+Mysql无限分类的方法汇总


Posted in PHP onMarch 02, 2015

无限分类是个老话题了,来看看PHP结合Mysql如何实现。

第一种方法

这种方法是很常见、很传统的一种,先看表结构

表:category
id int 主键,自增
name varchar 分类名称
pid int 父类id,默认0
顶级分类的 pid 默认就是0了。当我们想取出某个分类的子分类树的时候,基本思路就是递归,当然,出于效率问题不建议每次递归都查询数据库,通常的做法是先讲所有分类取出来,保存到PHP数组里,再进行处理,最后还可以将结果缓存起来以提高下次请求的效率。

先来构建一个原始数组,这个直接从数据库中拉出来就行:

$categories = array(

    array('id'=>1,'name'=>'电脑','pid'=>0),

    array('id'=>2,'name'=>'手机','pid'=>0),

    array('id'=>3,'name'=>'笔记本','pid'=>1),

    array('id'=>4,'name'=>'台式机','pid'=>1),

    array('id'=>5,'name'=>'智能机','pid'=>2),

    array('id'=>6,'name'=>'功能机','pid'=>2),

    array('id'=>7,'name'=>'超级本','pid'=>3),

    array('id'=>8,'name'=>'游戏本','pid'=>3),

);

目标是将它转化为下面这种结构

电脑
    笔记本
        超级本
        游戏本
    台式机
手机
    智能机
    功能机
用数组来表示的话,可以增加一个 children 键来存储它的子分类:

array(

    //1对应id,方便直接读取

    1 => array(

        'id'=>1,

        'name'=>'电脑',

        'pid'=>0,

        children=>array(

            &array(

                'id'=>3,

                'name'=>'笔记本',

                'pid'=>1,

                'children'=>array(

                    //此处省略

                )

            ),

            &array(

                'id'=>4,

                'name'=>'台式机',

                'pid'=>1,

                'children'=>array(

                    //此处省略

                )

            ),

        )

    ),

    //其他分类省略

)

处理过程:

$tree = array();

//第一步,将分类id作为数组key,并创建children单元

foreach($categories as $category){

    $tree[$category['id']] = $category;

    $tree[$category['id']]['children'] = array();

}

//第二部,利用引用,将每个分类添加到父类children数组中,这样一次遍历即可形成树形结构。

foreach ($tree as $k=>$item) {

    if ($item['pid'] != 0) {

        $tree[$item['pid']]['children'][] = &$tree[$k];

    }

}

print_r($tree);

打印结果如下:

Array

(

    [1] => Array

        (

            [id] => 1

            [name] => 电脑

            [pid] => 0

            [children] => Array

                (

                    [0] => Array

                        (

                            [id] => 3

                            [name] => 笔记本

                            [pid] => 1

                            [children] => Array

                                (

                                    [0] => Array

                                        (

                                            [id] => 7

                                            [name] => 超级本

                                            [pid] => 3

                                            [children] => Array

                                                (

                                                )

                                        )

                                    [1] => Array

                                        (

                                            [id] => 8

                                            [name] => 游戏本

                                            [pid] => 3

                                            [children] => Array

                                                (

                                                )

                                        )

                                )

                        )

                    [1] => Array

                        (

                            [id] => 4

                            [name] => 台式机

                            [pid] => 1

                            [children] => Array

                                (

                                )

                        )

                )

        )

    [2] => Array

        (

            [id] => 2

            [name] => 手机

            [pid] => 0

            [children] => Array

                (

                    [0] => Array

                        (

                            [id] => 5

                            [name] => 智能机

                            [pid] => 2

                            [children] => Array

                                (

                                )

                        )

                    [1] => Array

                        (

                            [id] => 6

                            [name] => 功能机

                            [pid] => 2

                            [children] => Array

                                (

                                )

                        )

                )

        )

    [3] => Array

        (

            [id] => 3

            [name] => 笔记本

            [pid] => 1

            [children] => Array

                (

                    [0] => Array

                        (

                            [id] => 7

                            [name] => 超级本

                            [pid] => 3

                            [children] => Array

                                (

                                )

                        )

                    [1] => Array

                        (

                            [id] => 8

                            [name] => 游戏本

                            [pid] => 3

                            [children] => Array

                                (

                                )

                        )

                )

        )

    [4] => Array

        (

            [id] => 4

            [name] => 台式机

            [pid] => 1

            [children] => Array

                (

                )

        )

    [5] => Array

        (

            [id] => 5

            [name] => 智能机

            [pid] => 2

            [children] => Array

                (

                )

        )

    [6] => Array

        (

            [id] => 6

            [name] => 功能机

            [pid] => 2

            [children] => Array

                (

                )

        )

    [7] => Array

        (

            [id] => 7

            [name] => 超级本

            [pid] => 3

            [children] => Array

                (

                )

        )

    [8] => Array

        (

            [id] => 8

            [name] => 游戏本

            [pid] => 3

            [children] => Array

                (

                )

        )

)

优点:关系清楚,修改上下级关系简单。

缺点:使用PHP处理,如果分类数量庞大,效率也会降低。

第二种方法

这种方法是在表字段中增加一个path字段:

表:category
id int 主键,自增
name varchar 分类名称
pid int 父类id,默认0
path varchar 路径
示例数据:

id        name        pid        path
1         电脑        0          0
2         手机        0          0
3         笔记本      1          0-1
4         超级本      3          0-1-3
5         游戏本      3          0-1-3
path字段记录了从根分类到上一级父类的路径,用id+'-'表示。

这种方式,假设我们要查询电脑下的所有后代分类,只需要一条sql语句:

select id,name,path from category where path like (select concat(path,'-',id,'%') as path from category where id=1);
结果:

+----+-----------+-------+
| id | name      | path  |
+----+-----------+-------+
| 3  | 笔记本 | 0-1   |
| 4  | 超级本 | 0-1-3 |
| 5  | 游戏本 | 0-1-3 |
+----+-----------+-------+
这种方式也被很多人所采纳,我总结了下:

优点:查询容易,效率高,path字段可以加索引。

缺点:更新节点关系麻烦,需要更新所有后辈的path字段。

以上就是本文的全部内容了,两种方式,你喜欢哪种?希望大家能够喜欢。

PHP 相关文章推荐
用php+mysql一个名片库程序
Oct 09 PHP
js和php邮箱地址验证的实现方法
Jan 09 PHP
PHP获取QQ达人QQ信息的方法
Mar 05 PHP
php 批量查询搜狗sogou代码分享
May 17 PHP
最新版本PHP 7 vs HHVM 多角度比较
Feb 14 PHP
PHP实现文件上传与下载实例与总结
Mar 13 PHP
AJAX PHP无刷新form表单提交的简单实现(推荐)
Sep 09 PHP
php中strtotime函数性能分析
Nov 20 PHP
DWZ+ThinkPHP开发时遇到的问题分析
Dec 12 PHP
thinkphp 验证码 的使用小结
May 07 PHP
详解PHP版本兼容之openssl调用参数
Jul 25 PHP
PHP时间日期增减操作示例【date strtotime实现加一天、加一月等操作】
Dec 21 PHP
Java和PHP在Web开发方面对比分析
Mar 01 #PHP
php中return的用法实例分析
Feb 28 #PHP
php多次include后导致全局变量global失效的解决方法
Feb 28 #PHP
Windows7下的php环境配置教程
Feb 28 #PHP
php数组使用规则分析
Feb 27 #PHP
php中stdClass的用法分析
Feb 27 #PHP
php中explode的负数limit用法分析
Feb 27 #PHP
You might like
BBS(php & mysql)完整版(二)
2006/10/09 PHP
php利用header函数实现文件下载时直接提示保存
2009/11/12 PHP
PHP获取用户访问IP地址的5种方法
2016/05/16 PHP
PHP中常用的魔术方法
2017/04/28 PHP
php使用ftp实现文件上传与下载功能
2017/07/21 PHP
javascript 常用功能总结
2012/03/18 Javascript
jquery判断密码强度的验证代码
2020/04/22 Javascript
浅谈Javascript数组(推荐)
2016/05/17 Javascript
js获取当前年月日-YYYYmmDD格式的实现代码
2016/06/01 Javascript
浅谈bootstrap源码分析之tab(选项卡)
2016/06/06 Javascript
jquery Ajax 全局调用封装实例详解
2017/01/16 Javascript
初探nodeJS
2017/01/24 NodeJs
AngularJS constant和value区别详解
2017/02/28 Javascript
使用gulp搭建本地服务器并实现模拟ajax
2017/04/05 Javascript
bootstrap table插件的分页与checkbox使用详解
2017/07/23 Javascript
深入浅出es6模板字符串
2017/08/26 Javascript
vue.js 实现评价五角星组件的实例代码
2018/08/13 Javascript
基于vue实现一个禅道主页拖拽效果
2019/05/27 Javascript
vue实现树状表格效果
2020/12/29 Vue.js
python实现在控制台输入密码不显示的方法
2015/07/02 Python
python使用str & repr转换字符串
2016/10/13 Python
Flask数据库迁移简单介绍
2017/10/24 Python
python3写的简单本地文件上传服务器实例
2018/06/04 Python
python+Django实现防止SQL注入的办法
2019/10/31 Python
关于pycharm 切换 python3.9 报错 ‘HTMLParser‘ object has no attribute ‘unescape‘ 的问题
2020/11/24 Python
Html5移动端适配IphoneX等机型的方法
2019/06/25 HTML / CSS
CSS代码检查工具stylelint的使用方法详解
2021/03/27 HTML / CSS
会计找工作求职信范文
2013/12/09 职场文书
家长学校实施方案
2014/03/15 职场文书
人力资源管理专业毕业生自荐书
2014/05/25 职场文书
法人委托书范本
2014/09/15 职场文书
学校师德师风整改措施
2014/10/27 职场文书
地道战观后感500字
2015/06/04 职场文书
签证工作证明模板
2015/06/15 职场文书
道士塔读书笔记
2015/06/30 职场文书
Python Django / Flask如何使用Elasticsearch
2022/04/19 Python