实现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
php 禁止页面缓存输出
Jan 07 PHP
php ctype函数中文翻译和示例
Mar 21 PHP
给ECShop添加最新评论
Jan 07 PHP
PHP编程计算日期间隔天数的方法
Apr 26 PHP
php获取微信共享收货地址的方法
Dec 21 PHP
php strftime函数的详细用法
Jun 21 PHP
laravel5实现微信第三方登录功能
Dec 06 PHP
PHP实现二维数组按照指定的字段进行排序算法示例
Apr 23 PHP
php使用gearman进行任务分发操作实例详解
Feb 26 PHP
TP5框架实现一次选择多张图片并预览的方法示例
Apr 04 PHP
Nginx+php配置文件及原理解析
Dec 09 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
Array of country list in PHP with Zend Framework
2011/10/17 PHP
php获取淘宝分类id示例
2014/01/16 PHP
PHP中使用虚代理实现延迟加载技术
2014/11/05 PHP
PHP输入输出流学习笔记
2015/05/12 PHP
PHP使用数组实现矩阵数学运算的方法示例
2017/05/29 PHP
javascript dom 基本操作小结
2010/04/11 Javascript
JavaScript获取Url里的参数
2014/12/18 Javascript
jQuery实现友好的轮播图片特效
2015/01/12 Javascript
jquery专业的导航菜单特效代码分享
2015/08/29 Javascript
JS与jQ读取xml文件的方法
2015/12/08 Javascript
Javascript设计模式之观察者模式(推荐)
2016/03/29 Javascript
超全面的vue.js使用总结
2017/02/12 Javascript
JS非空验证及邮箱验证的实例
2017/08/11 Javascript
Vue.js devtool插件安装后无法使用的解决办法
2017/11/27 Javascript
React中常见的动画实现的几种方式
2018/01/10 Javascript
layui 优化button按钮和弹出框的方法
2018/08/15 Javascript
微信小程序支付前端源码
2018/08/29 Javascript
[03:09]显微镜下的DOTA2第一期——带你走进华丽的DOTA2世界
2014/06/20 DOTA
[05:16]《大圣!大圣》——DOTA2新英雄齐天大圣配音李世宏老师专访
2016/12/13 DOTA
用Python的Flask框架结合MySQL写一个内存监控程序
2015/11/07 Python
详解Python函数作用域的LEGB顺序
2016/05/14 Python
动感网页相册 python编写简单文件夹内图片浏览工具
2016/08/17 Python
浅析Python中yield关键词的作用与用法
2016/11/29 Python
Python中使用Counter进行字典创建以及key数量统计的方法
2018/07/06 Python
Python直接赋值、浅拷贝与深度拷贝实例分析
2019/06/18 Python
Pytorch自己加载单通道图片用作数据集训练的实例
2020/01/18 Python
Python实例方法、类方法、静态方法区别详解
2020/09/05 Python
python实现学生通讯录管理系统
2021/02/25 Python
简单的HTML5初步入门教程
2015/09/29 HTML / CSS
Microsoft Advertising美国:微软搜索广告
2019/05/01 全球购物
意大利自行车商店:Cingolani Bike Shop
2019/09/03 全球购物
英文简历中的自我评价用语
2013/12/09 职场文书
分居协议书范本
2014/11/03 职场文书
先进教师个人总结
2015/02/11 职场文书
go语言中切片与内存复制 memcpy 的实现操作
2021/04/27 Golang
React + Threejs + Swiper 实现全景图效果的完整代码
2021/06/28 Javascript