南强小屋 Design By 杰米
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~闪人~
数据库的结构很简单:
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的无限分类实现想法~
南强小屋 Design By 杰米
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
南强小屋 Design By 杰米
暂无帖几个PHP的无限分类实现想法~的评论...
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。