实现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中用foreach来操作数组的代码
Jul 17 PHP
linux实现php定时执行cron任务详解
Dec 24 PHP
百度ping方法使用示例 自动ping百度
Jan 26 PHP
php中AES加密解密的例子小结
Feb 18 PHP
Linux操作系统安装LAMP环境
Jun 26 PHP
Symfony2学习笔记之模板用法详解
Mar 17 PHP
Laravel学习笔记之Artisan命令生成自定义模板的方法
Nov 22 PHP
PHP数组遍历的几种常见方式总结
Feb 15 PHP
PHP实现网站应用微信登录功能详解
Apr 11 PHP
TP5.0框架实现无限极回复功能的方法分析
May 04 PHP
Laravel框架处理用户的请求操作详解
Dec 20 PHP
利用PHP内置SERVER开启web服务(本地开发使用)
Jan 22 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 和 MySQL 时区的一点总结
2008/03/26 PHP
php DOS攻击实现代码(附如何防范)
2012/05/29 PHP
PHP命名空间(Namespace)简明教程
2014/06/11 PHP
PHP使用FFmpeg获取视频播放总时长与码率等信息
2016/09/13 PHP
php利用fsockopen GET/POST提交表单及上传文件
2017/05/22 PHP
七种PHP开发环境搭建工具
2020/06/28 PHP
JavaScript 组件之旅(四):测试 JavaScript 组件
2009/10/28 Javascript
javascript 折半查找字符在数组中的位置(有序列表)
2010/12/09 Javascript
js编码、解码函数介绍及其使用示例
2013/09/05 Javascript
节点的插入之append()和appendTo()的用法介绍
2014/01/13 Javascript
用console.table()调试javascript
2014/09/04 Javascript
jQuery使用load()方法载入另外一个网页文件内的指定标签内容到div标签的方法
2015/03/25 Javascript
Node.js服务器环境下使用Mock.js拦截AJAX请求的教程
2016/05/23 Javascript
JavaScript 身份证号有效验证详解及实例代码
2016/10/20 Javascript
解决Vue开发中对话框被遮罩层挡住的问题
2018/11/26 Javascript
ajax跨域访问遇到的问题及解决方案
2019/05/23 Javascript
微信域名检测接口调用演示步骤(含PHP、Python)
2019/12/08 Javascript
在react中使用vue的状态管理的方法示例
2020/05/02 Javascript
Javascript前端下载后台传来的文件流代码实例
2020/08/18 Javascript
PyQt5打开文件对话框QFileDialog实例代码
2018/02/07 Python
python使用生成器实现可迭代对象
2018/03/20 Python
Python获取二维矩阵每列最大值的方法
2018/04/03 Python
使用Python实现企业微信的自动打卡功能
2019/04/30 Python
Python在OpenCV里实现极坐标变换功能
2019/09/02 Python
Python对Excel按列值筛选并拆分表格到多个文件的代码
2019/11/05 Python
python随机生成库faker库api实例详解
2019/11/28 Python
关于numpy中eye和identity的区别详解
2019/11/29 Python
python实现拼接图片
2020/03/23 Python
解决pycharm中的run和debug失效无法点击运行
2020/06/09 Python
python中常见错误及解决方法
2020/06/21 Python
html5小技巧之通过document.head获取head元素
2014/06/04 HTML / CSS
Dockers鞋官网:Dockers Shoes
2018/11/13 全球购物
罗技英国官方网站:Logitech UK
2020/11/03 全球购物
自荐信要包含哪些内容
2013/11/06 职场文书
记帐员岗位责任制
2014/02/08 职场文书
浪漫婚礼主持词开场白
2015/11/24 职场文书