Welcome

首页 / 网页编程 / PHP / 自己前几天写的无限分类类

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

 主要思想来自: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"]." "; 
        } 
    } 
/*-------private-----------------------------------*/ 

    function error($msg){ 
        die("ERROR : file ".__FILE__." function ".$msg); 
    } 

?>