当前位置: 首页 > 图文教程 > 网络编程 > PHP > 无限分类与树型论坛的实现方法

PHP
mysql5的sql文件导入到mysql4的方法
sqlyog 中文乱码问题的设置方法
PHP CURL函数库
PHP 面向对象改进后的一点说明
攻克CakePHP系列一 连接MySQL数据库
CakePHP去除默认显示的标题及图标的方法
攻克CakePHP系列二 表单数据显示
攻克CakePHP系列三 表单数据增删改
smarty的保留变量问题
PHP syntax error, unexpected $end 错误的一种原因及解决
如何使用PHP编程说明
php合并数组array_merge函数运算符加号与的区别
php初学者写及时补给skype用户充话费的小程序
MySql 按时间段查询数据方法(实例说明)
Php Cookie的一个使用注意点
PHP程序61条面向对象分析设计的经验小结
令PHP初学者头疼十四条问题大总结
mysql limit查询优化分析
使用Limit参数优化MySQL查询的方法
方便实用的PHP生成静态页面类(非smarty)

PHP 中的 无限分类与树型论坛的实现方法


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-11-03   浏览: 183 ::
收藏到网摘: n/a

无限分类与树型论坛的实现方法
――浮点型字段排序法
Joe Teng 2005.6.12

在此我不想讨论其他实现方法的利与弊。
既然是使用字段排序,那么我们便设一个名为order的字段。问题是,在这里是使用整数还是使用浮点数类型呢?考虑到会有在两个连续order值中间插入新值的可能,自然是需要使用浮点类型了。
建一个menus表,我们还需要以下字段:
id : 类别编号
mainid : 主分类编号,但不作具体分类使用。如果在树型论坛里,它代表的是主题id
parentid : 父类编号
level : 类别级别,作用其实是方便显示的时候作其他处理
info : 类别名称等。
由此可以得到menus的表结构:
CREATE TABLE `menus` (
`id` INT( 10 ) UNSIGNED NOT NULL AUTO_INCREMENT ,
`mainid` INT( 10 ) UNSIGNED NOT NULL ,
`parentid` INT( 10 ) UNSIGNED NOT NULL ,
`order` FLOAT UNSIGNED NOT NULL ,
`level` SMALLINT( 5 ) UNSIGNED NOT NULL ,
`info` VARCHAR( 128 ) NOT NULL ,
INDEX ( `mainid` , `parentid` , `order` , `level` ) ,
UNIQUE (
`id`
)
) TYPE = MYISAM ;

很容易可以看出,输入的时候是如此简单便实现树结构了:
SELECT * FROM `menus` ORDER BY `mainid` ASC, `order` ASC ;
前提是添加类别的时候,order能正确排序。

添加根分类:
很简单,取得上一个主类的mainid, 如A_mainid,则新根分类的mainid则为A_mainid + 1。parentid 为 0 , order 为0, level也为0, info则自行设定。

添加子分类:
核心思想是,取得新增子分类的前一个分类的order以及它后一个分类的order。
取得前一个分类的order是这里的难点,因为涉及到同级与非同级的情况。非同级的情况很简单,新增别类的前一个order其实就是它的父类的order。如果有同级分类,情况就很复杂了,因为它前面的同级分类有可能会拥有子分类,子分类下又可能还会有子分类,如此下来,要取得前一个order就很难了。
解决的办法有两个:
1.取得新增类同级的前一个类别,如类别A的ID,使用递归的方法,直到取得A类别下最后最小分类的order,那便是要新增分类的前一个order了。这种方法的缺点是,如果A类别下有很多子分类,那么递归需要一定的时间。这种方法适用于普通的分类处理,不适用于树型论坛。不过总体来说,因为是添加类别的时候才使用递归,输出类别的时候跟前面一样,效率还是很高的。
2.作一个记录,记录着与A有关联的最后order。于是我们就需要增加一个表,建利关系树。这种关系树做起来很简单。表结构如下:
CREATE TABLE `menu_tree` (
`mainid` int(10) unsigned NOT NULL default '0',
`tree` text NOT NULL,
`order` float unsigned NOT NULL default '0',
KEY `mainid` (`mainid`,`order`),
FULLTEXT KEY `tree` (`tree`)
) TYPE=MyISAM;
(构建方式请看我后面给出的源码)
取得前一个order之后,要取得后一个order就很简单了。取同mainid下大于前一个order的最小order便是了。如果存在后一个order,那么新增order就取前一个order与后一个order的平均值。如果不存在后一个order,那说明新增类别是main下的最小order,取大于前一个order的最小整数就行了。

主要实现方法便如上面说的。

处理方法

登陆 还没注册?