自己前几天写的无限分类类

  前一周写的吧,使用中效果还不错。

  主要思想来自:http://www.phpobject.net/b...[url=http://www.phpobject.net/blog/read.php?49][/url]

  这里就不多解释原理了,直接发代码。

  PS:这里代码是不能直接使用的,必须结合我的一些其他库类。应该说思想才是最重要的,这里主要提供一种分类的思路。

  

复制代码 代码如下:

  <?

  /**

  --

  -- 表的结构 `daxue8_category`

  --

  CREATE TABLE `daxue8_category` (

  `cid` smallint(6) NOT NULL auto_increment,

  `pid` smallint(6) NOT NULL default '0',

  `level` smallint(6) NOT NULL default '0',

  `cname` char(64) NOT NULL default '',

  `lft` smallint(6) NOT NULL default '0',

  `rgt` smallint(6) NOT NULL default '0',

  `uid` mediumint(8) NOT NULL default '0',

  `username` char(32) NOT NULL default '',

  `ctime` int(10) NOT NULL default '0',

  `cstate` tinyint(1) NOT NULL default '0',

  `gnum` mediumint(8) NOT NULL default '0',

  `orderstyle` smallint(3) NOT NULL default '0',

  PRIMARY KEY  (`cid`)

  ) TYPE=MyISAM AUTO_INCREMENT=2 ;

  --

  -- 导出表中的数据 `daxue8_category`

  --

  INSERT INTO `daxue8_category` VALUES (1, 0, 1, 'root', 1, 2, 0, '管理员', 1163608814, 1, 0, 0);

  */

  class category

  {

  var $module;

  var $tbname;

  function category()

  {

  $this->tbname=TB_PREX.'_category';

  $this->module=new module($this->tbname);

  }

  /**

  * 增加子节点

  * @param array $node 待增加子节点的属性

  * @param int $pid 父节点的ID

  */

  function add($node,$pid){

  //检查是否已经存在该节点

  if($node_exist=$this->module->detail('where pid='.$pid.' and cname=\''.$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.'` set lft=lft+2 where lft>'.$pnode['rgt']);

  $this->module->query('update `'.$this->tbname.'` set rgt=rgt+2 where rgt>='.$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

  *

  */

  function delete($cid,$delete_childern=false)

  {

  //获取节点信息

  $node=$this->get_by_cid($cid);

  if(($this->child_num($node)>0)&&(!$delete_childern))$this->error(__FUNCTION__.'():该节点存在子节点!');

  //删除该节点及其所有子节点

  $this->module->delete('where lft between '.$node['lft'].' and '.$node['rgt']);

  //修改相应的左右键值

  $plus=$node['rgt']-$node['lft']+1;

  $this->module->query('update `'.$this->tbname.'` set lft=lft-'.$plus.' where lft>'.$node['rgt']);

  $this->module->query('update `'.$this->tbname.'` set rgt=rgt-'.$plus.' where rgt>'.$node['rgt']);

  return true;

  }

  /**

  * 更新一个节点

  * @param array $set更新集

  * @param int $cid 更新的节点的主键ID

  */

  function update($set,$cid){

  return $this->module->update($set,'where cid='.$cid);

  }

  /**

  * 选取节点及其子节点

  * @param int $cid节点的主键ID

  * @param int $deep选取深度

  */

  function select($cid,$deep=0)

  {

  //获取节点信息

  $node=$this->get_by_cid($cid);

  $where='where lft between '.$node['lft'].' and '.$node['rgt'];

  if(!empty($deep))$where.=' and level<'.$node['level']+$deep;

  if($deep==1){

  $where.=' order by orderstyle desc';

  }else{

  $where.=' order by lft asc';

  }

  return $this->module->select($where);

  }

  /**

  * 获取父节点路径

  * @param int $cid 节点的ID

  */

  function get_parent($cid)

  {

  $node=$this->get_by_cid($cid);

  return $this->module->select('where lft<='.$node['lft'].' and rgt>='.$node['rgt'].' order by lft asc');

  }

  /**

  * 选取子节点

  * @param int $cid节点的主键ID

  * @param int $deep选取深度

  */

  function get_children($pid,$deep=0){

  //获取节点信息

  $pnode=$this->get_by_cid($pid);

  $where='where lft>'.$pnode['lft'].' and rgt<'.$pnode['rgt'];

  if(!empty($deep))$where.=' and level<='.($pnode['level']+$deep);

  if($deep==1){

  $where.=' order by orderstyle desc';

  }else{

  $where.=' order by lft asc';

  }

  return $this->module->select($where);

  }

  /**

  * 获取第deep层子节点

  * @param int $cid节点的主键ID

  * @param int $deep选取深度

  */

  function get_level_children($pid,$deep){

  //获取节点信息

  $pnode=$this->get_by_cid($pid);

  $where='where lft>'.$pnode['lft'].' and rgt<'.$pnode['rgt'];

  $where.=' and level='.($pnode['level']+$deep);

  $where.=' order by orderstyle desc';

  return $this->module->select($where);

  }

  /**

  * 获取节点信息

  * @param $cid 节点的主键ID

  * @return array $node

  */

  function get_by_cid($cid){

  $node=$this->module->detail('where cid='.$cid);

  if(!$node)$this->error(__FUNCTION__.'():获取节点'.$cid.'失败!');

  return $node;

  }

  /**

  * 获取子节点的数目

  * @param array $node 节点信息

  * @return num

  */

  function child_num($node){

  return ($node['rgt']-$node['lft']-1)/2;

  }

  /**

  * 按照层次显示分类

  * @param int $cid节点的主键ID

  * @output

  */

  function display($cid)

  {

  $nodes=$this->select($cid);

  foreach($nodes as $node){

  echo str_repeat('   ',$node['level']-1).$node['cname']."\n";

  }

  }

  /*-------private-----------------------------------*/

  function error($msg){

  die('ERROR : file '.__FILE__.' function '.$msg);

  }

  }

  ?>