主要思想来自:http://www.phpobject.net/b...[url=http://www.phpobject.net/blog/read.php?49][/url]
这里就不多解释原理了,直接发代码。
PS:这里代码是不能直接使用的,必须结合我的一些其他库类。应该说思想才是最重要的,这里主要提供一种分类的思路。
复制代码 代码如下:
/**
--
--表的结构`daxue8_category`
--
CREATETABLE`daxue8_category`(
`cid`smallint(6)NOTNULLauto_increment,
`pid`smallint(6)NOTNULLdefault'0',
`level`smallint(6)NOTNULLdefault'0',
`cname`char(64)NOTNULLdefault'',
`lft`smallint(6)NOTNULLdefault'0',
`rgt`smallint(6)NOTNULLdefault'0',
`uid`mediumint(8)NOTNULLdefault'0',
`username`char(32)NOTNULLdefault'',
`ctime`int(10)NOTNULLdefault'0',
`cstate`tinyint(1)NOTNULLdefault'0',
`gnum`mediumint(8)NOTNULLdefault'0',
`orderstyle`smallint(3)NOTNULLdefault'0',
PRIMARYKEY(`cid`)
)TYPE=MyISAMAUTO_INCREMENT=2;
--
--导出表中的数据`daxue8_category`
--
INSERTINTO`daxue8_category`VALUES(1,0,1,'root',1,2,0,'管理员',1163608814,1,0,0);
*/
classcategory
{
var$module;
var$tbname;
functioncategory()
{
$this->tbname=TB_PREX.'_category';
$this->module=newmodule($this->tbname);
}
/**
*增加子节点
*@paramarray$node待增加子节点的属性
*@paramint$pid父节点的ID
*/
functionadd($node,$pid){
//检查是否已经存在该节点
if($node_exist=$this->module->detail('wherepid='.$pid.'andcname=''.$node['cname'].''')){
//$this->error(__FUNCTION__.'():该节点'.$node['cname'].'已经存在!');
//print_r($node_exist);
return$node_exist['cid'];
}
//获取父节点信息
$pnode=$this->get_by_cid($pid);
//更新其他节点
$this->module->query('update`'.$this->tbname.'`setlft=lft+2wherelft>'.$pnode['rgt']);
$this->module->query('update`'.$this->tbname.'`setrgt=rgt+2wherergt>='.$pnode['rgt']);
//插入新节点
$node['pid']=$pid;
$node['lft']=$pnode['rgt'];
$node['rgt']=$pnode['rgt']+1;
$node['level']=$pnode['level']+1;//层次加一
return$this->module->add($node);
}
/**
*删除节点
*@param$cid待删除的节点的ID
*@param$delete_childern如果该节点存在子节点,是否强制删除。设置未true,则当存在子节点的时候,删除失败,返回false
*
*/
functiondelete($cid,$delete_childern=false)
{
//获取节点信息
$node=$this->get_by_cid($cid);
if(($this->child_num($node)>0)&&(!$delete_childern))$this->error(__FUNCTION__.'():该节点存在子节点!');
//删除该节点及其所有子节点
$this->module->delete('wherelftbetween'.$node['lft'].'and'.$node['rgt']);
//修改相应的左右键值
$plus=$node['rgt']-$node['lft']+1;
$this->module->query('update`'.$this->tbname.'`setlft=lft-'.$plus.'wherelft>'.$node['rgt']);
$this->module->query('update`'.$this->tbname.'`setrgt=rgt-'.$plus.'wherergt>'.$node['rgt']);
returntrue;
}
/**
*更新一个节点
*@paramarray$set更新集
*@paramint$cid更新的节点的主键ID
*/
functionupdate($set,$cid){
return$this->module->update($set,'wherecid='.$cid);
}
/**
*选取节点及其子节点
*@paramint$cid节点的主键ID
*@paramint$deep选取深度
*/
functionselect($cid,$deep=0)
{
//获取节点信息
$node=$this->get_by_cid($cid);
$where='wherelftbetween'.$node['lft'].'and'.$node['rgt'];
if(!empty($deep))$where.='andlevel<'.$node['level']+$deep;
if($deep==1){
$where.='orderbyorderstyledesc';
}else{
$where.='orderbylftasc';
}
return$this->module->select($where);
}
/**
*获取父节点路径
*@paramint$cid节点的ID
*/
functionget_parent($cid)
{
$node=$this->get_by_cid($cid);
return$this->module->select('wherelft<='.$node['lft'].'andrgt>='.$node['rgt'].'orderbylftasc');
}
/**
*选取子节点
*@paramint$cid节点的主键ID
*@paramint$deep选取深度
*/
functionget_children($pid,$deep=0){
//获取节点信息
$pnode=$this->get_by_cid($pid);
$where='wherelft>'.$pnode['lft'].'andrgt<'.$pnode['rgt'];
if(!empty($deep))$where.='andlevel<='.($pnode['level']+$deep);
if($deep==1){
$where.='orderbyorderstyledesc';
}else{
$where.='orderbylftasc';
}
return$this->module->select($where);
}
/**
*获取第deep层子节点
*@paramint$cid节点的主键ID
*@paramint$deep选取深度
*/
functionget_level_children($pid,$deep){
//获取节点信息
$pnode=$this->get_by_cid($pid);
$where='wherelft>'.$pnode['lft'].'andrgt<'.$pnode['rgt'];
$where.='andlevel='.($pnode['level']+$deep);
$where.='orderbyorderstyledesc';
return$this->module->select($where);
}
/**
*获取节点信息
*@param$cid节点的主键ID
*@returnarray$node
*/
functionget_by_cid($cid){
$node=$this->module->detail('wherecid='.$cid);
if(!$node)$this->error(__FUNCTION__.'():获取节点'.$cid.'失败!');
return$node;
}
/**
*获取子节点的数目
*@paramarray$node节点信息
*@returnnum
*/
functionchild_num($node){
return($node['rgt']-$node['lft']-1)/2;
}
/**
*按照层次显示分类
*@paramint$cid节点的主键ID
*@output
*/
functiondisplay($cid)
{
$nodes=$this->select($cid);
foreach($nodesas$node){
echostr_repeat('',$node['level']-1).$node['cname']."n";
}
}
/*-------private-----------------------------------*/
functionerror($msg){
die('ERROR:file'.__FILE__.'function'.$msg);
}
}
?>