帖几个PHP的无限分类实现想法~


Posted in PHP onJanuary 02, 2007

1、做网站的一般都会遇到处理分类的问题, 偶来帖几个处理无限分类的例子
数据库的结构很简单:
id, fatcher_id, name, ......
这样的设计短小精悍,完全满足3NF..可以完全绝大多数要求,OK,让偶们看看这种数据库结构下的程序实现.

1.递归查询数据库
最要命的做法~也是最好实现的做法

类别1

类别1.1

类别1.1.1

类别1.2

类别2

类别2.1

类别3

类别3.1

类别3.2
......
为了生成这样的目录结构,程序递归一次就查询一次数据库,在您任何涉及分类的地方(翻页,查询....),数据库都会悲壮地操作硬盘....阿门~so~跳一下吧...
2.查询一次数据库,递归数组生成以上目录结构
帖一个大致的思路
function SelectList(&$Data, $RootID = 0')
{
     for($i = 0; $i < count($Data); $i++)
     {
           if($Data[$i]['UID'] == $RootID)
           {
                 ......//处理,直接生成HTML或者保存入数组都OK啦
                 $this->SelectRecursion($Data, $Data[$i]['ID'], $blank, $Match);
           }
     }
     return $this->Output;
}
这种强度的递归一般的网站系够用啦~不过碰到BT点的,有几K甚至上W的分类,递归一遍可能要百毫秒以上,在考虑并发的情况下....呵呵~我们再跳一下吧
3.查询一次数据库,非递归生成目录结构
这一步,程序的技巧来了~只对结果遍历一次就能生成上面那样的目录结构,想要把它格式化成网页的显示样式就很方便咯~下面的系别人写的,偶试过完全可行
function GetArray($RootID = 0)
{
     $Data      = array();

     $Data      = $tblObj->MapResult($tblObj->Select());

    $Output = Array();
    $i = 0;
    $len = Count($Data);
    if($RootID)
    {
        while($Data[$i]['UID'] != $RootID && $i < $len)      $i++;
    }
    $UpID   = $RootID;     //上个节点指向的分类父ID
    for($cnt = Count($Data); $i < $cnt;)   //历遍整个分类数组
    {
        $j = 0;     //初始化此次分类下子分类数据计数
        if ($UpID == $RootID)   //在第一次循环时将所有一级分类保存到$Output这个数组中
        {
          while($Data[$i]['UID'] == $UpID && $i < $len) //判断上一个节点是否为兄弟节点
          {
            $Output[$j] = $Data[$i];                   //保存该节点到Output这个数组中
            $tmp[$Data[$i]['ID']] = &$Output[$j]; //并且将该节点ID在Output中的位置保存起来.
            $i++;
            $j++;
          }
        }
        else
        {
          while($Data[$i]['UID'] == $UpID && $i < $len)
          {
            if($tmp[$UpID])
            {
                $tmp[$UpID]['Child'][$j] = $Data[$i];
                $tmp[$Data[$i]['ID']] = &$tmp[$UpID]['Child'][$j];   //保存该节点ID在Output中的位置
            }
            $i++;
            $j++;
          }
        }
        $UpID = $Data[$i]['UID'];
    }
    return $Output;
  }

程序看着好累人啊~这段代码的效率比上一段快了十几倍呢,强度系够大了...
不过....90%的网站用这样的代码都浪费啦~偶遇到过的网站分类一般都在四级以下,那么,还能再优化一下么?........再....再跳一下吧..
4.从数据库入手~
稍微改动一下数据库的结构,加一个layer的冗余字段,这个是db desing高手想出来的,偶把他帖出来而已
id         name       father_id       layer
1         总类别       0           000000
2         类别1           1           010000
3         类别1.1         2           010100
4         类别1.2         2           010200
5         类别2           1           020000
6         类别2.1         5           020100
7         类别3           1           030000
8         类别3.1         7           030100
9         类别3.2         7           030200
10         类别1.1.1         3           010101

现在按layer的大小来检索一下:SELECT * FROM Type_table_2 ORDER BY type_layer

列出记录集如下:

id         name       father_id       layer
1         总类别       0           000000
2         类别1           1           010000
3         类别1.1         2           010100
10         类别1.1.1         3           010101
4         类别1.2         2           010200
5         类别2           1           020000
6         类别2.1         5           020100
7         类别3           1           030000
8         类别3.1         7           030100
9         类别3.2         7           030200

看见了么~一次查询连目录结构都生成好咯~,这样程序就轻松很多了,只是多了维护layer字段的工作,这个例程中layer字段每一级能处理99个分类,如果有BT的应用,改大些就行了,呵呵,先分析你的需求吧

OK~OVER~闪人~

PHP 相关文章推荐
php检测图片木马多进制编程实践
Apr 11 PHP
linux下为php添加iconv模块的方法
Feb 28 PHP
PHP中使用foreach()遍历二维数组的简单实例
Jun 13 PHP
PHP实现带重试功能的curl连接示例
Jul 28 PHP
Thinkphp整合微信支付功能
Dec 14 PHP
简单解决微信文章图片防盗链问题
Dec 17 PHP
由php中字符offset特征造成的绕过漏洞详解
Jul 07 PHP
三个思路解决laravel上传文件报错:413 Request Entity Too Large问题
Nov 13 PHP
PHP 实现人民币小写转换成大写的方法及大小写转换函数
Nov 17 PHP
tp5框架使用composer实现日志记录功能示例
Jan 10 PHP
PHP的介绍以及优势详细分析
Sep 05 PHP
PHP Swoole异步MySQL客户端实现方法示例
Oct 24 PHP
PHP+MYSQL开发工具及资源收藏
Jan 02 #PHP
分享PHP入门的学习方法
Jan 02 #PHP
php中常用编辑器推荐
Jan 02 #PHP
PHP中的日期处理方法集锦
Jan 02 #PHP
PHP语法速查表
Jan 02 #PHP
require(),include(),require_once()和include_once()的异同
Jan 02 #PHP
开发大型 PHP 项目的方法
Jan 02 #PHP
You might like
PHP 函数语法介绍一
2009/06/14 PHP
简单的php数据库操作类代码(增,删,改,查)
2013/04/08 PHP
Codeigniter实现处理用户登录验证后的URL跳转
2014/06/12 PHP
PHP中的Trait 特性及作用
2016/04/03 PHP
PHP后期静态绑定实例浅析
2018/12/21 PHP
javascript 显示当前系统时间代码
2009/12/28 Javascript
js验证上传图片的方法
2015/05/12 Javascript
div实现自适应高度的textarea实现angular双向绑定
2017/01/08 Javascript
Javascript实现从小到大的数组转换成二叉搜索树
2017/06/13 Javascript
javaScript中封装的各种写法示例(推荐)
2017/07/03 Javascript
js分页之前端代码实现和请求处理
2017/08/04 Javascript
完美解决iview 的select下拉框选项错位的问题
2018/03/02 Javascript
layer.confirm()右边按钮实现href的例子
2019/09/27 Javascript
Vue + Element-ui的下拉框el-select获取额外参数详解
2020/08/14 Javascript
[01:22:19]EG vs TNC Supermajor小组赛B组败者组第一轮 BO3 第二场 6.2
2018/06/03 DOTA
Python中的条件判断语句基础学习教程
2016/02/07 Python
利用Celery实现Django博客PV统计功能详解
2017/05/08 Python
深入理解Django-Signals信号量
2019/02/19 Python
python2和python3应该学哪个(python3.6与python3.7的选择)
2019/10/01 Python
pandas按行按列遍历Dataframe的几种方式
2019/10/23 Python
selenium WebDriverWait类等待机制的实现
2020/03/18 Python
matplotlib 曲线图 和 折线图 plt.plot()实例
2020/04/17 Python
浅谈numpy中np.array()与np.asarray的区别以及.tolist
2020/06/03 Python
安装pyecharts1.8.0版本后导入pyecharts模块绘图时报错: “所有图表类型将在 v1.9.0 版本开始强制使用 ChartItem 进行数据项配置 ”的解决方法
2020/08/18 Python
购买大码女装:Lane Bryant
2016/09/07 全球购物
德国香水、化妆品和护理产品网上商店:Parfumdreams
2018/09/26 全球购物
Liu Jo西班牙官网:意大利服装品牌
2019/09/11 全球购物
印度手工编织服装和家居用品商店:Fabindi
2019/10/07 全球购物
什么是触发器(trigger)? 触发器有什么作用?
2013/09/18 面试题
RIP版本1跟版本2的区别
2013/12/30 面试题
中专自我鉴定范文
2013/10/16 职场文书
幼儿园元旦家长感言
2014/02/27 职场文书
特教教师先进事迹
2014/05/21 职场文书
Django展示可视化图表的多种方式
2021/04/08 Python
MySQL系列之十一 日志记录
2021/07/02 MySQL
一小时学会TensorFlow2之基本操作2实例代码
2021/09/04 Python