实现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导出oracle库的php代码
Apr 20 PHP
浅析php中三个等号(===)和两个等号(==)的区别
Aug 06 PHP
限制ckeditor上传图片文件大小的方法
Nov 15 PHP
修改ThinkPHP缓存为Memcache的方法
Jun 25 PHP
destoon实现首页显示供应、企业、资讯条数的方法
Jul 15 PHP
PHP中strnatcmp()函数“自然排序算法”进行字符串比较用法分析(对比strcmp函数)
Jan 07 PHP
php基于PDO连接MSSQL示例DEMO
Jul 13 PHP
php 判断过去离现在几年的函数(实例代码)
Nov 15 PHP
详解Yii2高级版引入bootstrap.js的一个办法
Mar 21 PHP
PHP魔术方法之__call与__callStatic使用方法
Jul 23 PHP
利用PHP访问MySql数据库的逻辑操作以及增删改查的实例讲解
Aug 30 PHP
php判断电子邮件是否正确方法
Dec 04 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
ThinkPHP中redirect用法分析
2014/12/05 PHP
汇总PHPmailer群发Gmail的常见问题
2016/02/24 PHP
解析PHP的Yii框架中cookie和session功能的相关操作
2016/03/17 PHP
(jQuery,mootools,dojo)使用适合自己的编程别名命名
2010/09/14 Javascript
仿新浪微博返回顶部的jquery实现代码
2012/10/01 Javascript
JavaScript 判断用户输入的邮箱及手机格式是否正确
2013/12/08 Javascript
jQuery设置与获取HTML,文本和值的简单实例
2014/02/26 Javascript
jquery实现的Banner广告收缩效果代码
2015/09/02 Javascript
js判断当前页面用什么浏览器打开的方法
2016/01/06 Javascript
jQuery实现的文字hover颜色渐变效果实例
2016/02/20 Javascript
JS与jQuery实现子窗口获取父窗口元素值的方法
2017/04/17 jQuery
nodejs利用ajax实现网页无刷新上传图片实例代码
2017/06/06 NodeJs
Angular 项目实现国际化的方法
2018/01/08 Javascript
nodejs实现解析xml字符串为对象的方法示例
2018/03/14 NodeJs
vue v-for循环重复数据无法添加问题解决方法【加track-by='索引'】
2019/03/15 Javascript
Vue v-model组件封装(类似弹窗组件)
2020/01/08 Javascript
详解JavaScript原型与原型链
2020/11/16 Javascript
javascript实现点击小图显示大图
2020/11/29 Javascript
用Python的urllib库提交WEB表单
2009/02/24 Python
python 查找文件夹下所有文件 实现代码
2009/07/01 Python
Python yield使用方法示例
2013/12/04 Python
用python + hadoop streaming 分布式编程(一) -- 原理介绍,样例程序与本地调试
2014/07/14 Python
python中文分词,使用结巴分词对python进行分词(实例讲解)
2017/11/14 Python
tensorflow构建BP神经网络的方法
2018/03/12 Python
在Python中分别打印列表中的每一个元素方法
2018/11/07 Python
对python内置map和six.moves.map的区别详解
2018/12/19 Python
如何修复使用 Python ORM 工具 SQLAlchemy 时的常见陷阱
2019/11/19 Python
python实现IOU计算案例
2020/04/12 Python
python函数中将变量名转换成字符串实例
2020/05/11 Python
html5-websocket基于远程方法调用的数据交互实现
2012/12/04 HTML / CSS
劳模事迹材料范文
2014/12/24 职场文书
个人总结格式范文
2015/03/09 职场文书
2015年“七七卢沟桥事变”纪念活动总结
2015/03/24 职场文书
学生会宣传部竞选稿
2015/11/21 职场文书
python process模块的使用简介
2021/05/14 Python
java executor包参数处理功能 
2022/02/15 Java/Android