实现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个人网站架设连环讲(三)
Oct 09 PHP
Uchome1.2 1.5 代码学习 common.php
Apr 24 PHP
PHP 获取MSN好友列表的代码(2009-05-14测试通过)
Sep 09 PHP
PHP发明人谈MVC和网站设计架构 貌似他不支持php用mvc
Jun 04 PHP
table标签的结构与合并单元格的实现方法
Jul 24 PHP
PHP解码unicode编码的中文字符代码分享
Aug 13 PHP
PHP7安装Redis扩展教程【Linux与Windows平台】
Sep 30 PHP
php导出csv文件,可导出前导0实例代码
Nov 16 PHP
PHP二维数组去重实例分析
Nov 18 PHP
PHP实现二维数组去重功能示例
Jan 12 PHP
PHP多维数组排序array详解
Nov 21 PHP
Laravel框架实现即点即改功能的方法分析
Oct 31 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
PHP禁止页面缓存的代码
2011/10/23 PHP
解析php如何将日志写进syslog
2013/06/28 PHP
PHP中使用匿名函数操作数据库的例子
2014/11/17 PHP
php输出全球各个时区列表的方法
2015/03/31 PHP
实现PHP框架系列文章(6)mysql数据库方法
2016/03/04 PHP
定位地理位置PHP判断员工打卡签到经纬度是否在打卡之内
2019/05/23 PHP
jquery获取URL中参数解决中文乱码问题的两种方法
2013/12/18 Javascript
js实现网页倒计时、网站已运行时间功能的代码3例
2014/04/14 Javascript
javascript实现类似超链接的效果
2014/12/26 Javascript
javascript实现根据iphone屏幕方向调用不同样式表的方法
2015/07/13 Javascript
jQuery中slidedown与slideup方法用法示例
2016/09/16 Javascript
BootStrap 超链接变按钮的实现方法
2016/09/25 Javascript
Bootstrap基本组件学习笔记之input输入框组(9)
2016/12/07 Javascript
js实现时间轴自动排列效果
2017/03/09 Javascript
微信小程序 弹框和模态框实现代码
2017/03/10 Javascript
JS中SetTimeout和SetInterval使用初探
2017/03/23 Javascript
VueJS组件之间通过props交互及验证的方式
2017/09/04 Javascript
Vue CLI2升级至Vue CLI3的方法步骤
2019/05/20 Javascript
微信小程序如何调用新闻接口实现列表循环
2019/07/02 Javascript
Vue+webpack实现懒加载过程解析
2020/02/17 Javascript
Python中使用摄像头实现简单的延时摄影技术
2015/03/27 Python
最基础的Python的socket编程入门教程
2015/04/23 Python
Python yield 使用浅析
2015/05/28 Python
详解使用python的logging模块在stdout输出的两种方法
2017/05/17 Python
python os.listdir按文件存取时间顺序列出目录的实例
2018/10/21 Python
Python对Excel按列值筛选并拆分表格到多个文件的代码
2019/11/05 Python
python科学计算之numpy——ufunc函数用法
2019/11/25 Python
Python tensorflow实现mnist手写数字识别示例【非卷积与卷积实现】
2019/12/19 Python
Python偏函数Partial function使用方法实例详解
2020/06/17 Python
CSS3+font字体文件实现圆形半透明菜单具体步骤(图解)
2013/06/03 HTML / CSS
LN-CC日本:高端男装和女装的奢侈时尚目的地
2019/09/01 全球购物
文科生自我鉴定
2014/02/15 职场文书
党的群众路线学习笔记
2014/11/06 职场文书
敬老院活动感想
2015/08/07 职场文书
Nginx使用Lua模块实现WAF的原理解析
2021/09/04 Servers
TaiShan 200服务器安装Ubuntu 18.04的图文教程
2022/06/28 Servers