zoukankan      html  css  js  c++  java
  • 数据库结果为 基于左右值排序的无限分类算法

    <?php 
    /** 
        * 基于左右值排序的无限分类算法 
        * 数据库结果为 
    CREATE TABLE om_catagory ( 
         CatagoryID int(10) unsigned NOT NULL auto_increment, 
        Name varchar(50) default '', 
         Lft int(10) unsigned NOT NULL default '0', 
         Rgt int(10) unsigned NOT NULL default '0', 
         PRIMARY KEY (id), 
         KEY lft (lft), 
         KEY rgt (rgt) 

        * 更多的关于左右值排序的例子 
        * http://www.chinaunix.net/jh/27/239532.html(http://dev.mysql.com/tech-resources/articles/hierarchical-data.html
        * @author [email]psdshow@yahoo.com.cn[/email] 
        * @version         1.0 
        * @copyright psdshow 
        * 欢迎光临我的个人日志 http://www.dayanmei.com 
        */ 
    class sortclass 
    {


    /** 
        * Description 
        * @var          
        * @since         1.0 
        * @access     private 
        */ 
    var $db;


    /** 
        * Description 
        * @var          
        * @since         1.0 
        * @access     private 
        */ 
    var $tablefix;


    /** 
        * Short description. 
        * 构造函数,引入数据库操作类函数 
        * Detail description 
        * @param         none 
        * @global         none 
        * @since         1.0 
        * @access         private 
        * @return         void 
        * @update         date time 
    */ 
    function sortclass() 

    global $db; 
    $this->db=$db; 
    $this->tablefix="om_"; 
    } // end func


    /** 
        * Short description. 
        * 增加新的分类 
        * Detail description 
        * @param         none 
        * @global         none 
        * @since         1.0 
        * @access         private 
        * @return         void 
        * @update         date time 
    */ 
    function addsort($CatagoryID,$SortName) 

    if($CatagoryID==0){ 
        $Lft=0; 
        $Rgt=1; 
        }else{ 
        $Result=$this->checkcatagory($CatagoryID); 
        //取得父类的左值,右值 
        $Lft=$Result['Lft']; 
        $Rgt=$Result['Rgt']; 
        $this->db->query("UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`+2 WHERE `Lft`>$Rgt"); 
        $this->db->query("UPDATE `".$this->tablefix."catagory` SET `Rgt`=`Rgt`+2 WHERE `Rgt`>=$Rgt"); 
        }


    //插入 
    if($this->db->query("INSERT INTO `".$this->tablefix."catagory` SET `Lft`='$Rgt',`Rgt`='$Rgt'+1,`Name`='$SortName'")){ 
        //$this->referto("成功增加新的类别","JAVASCRIPT:HISTORY.BACK(1)",3); 
        return 1; 
        }else{ 
        //$this->referto("增加新的类别失败了","JAVASCRIPT:HISTORY.BACK(1)",3); 
        return -1; 
        } 
    } // end func

    /** 
        * Short description. 
        * 删除类别 
        * Detail description 
        * @param         none 
        * @global         none 
        * @since         1.0 
        * @access         private 
        * @return         void 
        * @update         date time 
    */ 
    function deletesort($CatagoryID) 

    //取得被删除类别的左右值,检测是否有子类,如果有就一起删除 
    $Result=$this->checkcatagory($CatagoryID); 
    $Lft=$Result['Lft']; 
    $Rgt=$Result['Rgt']; 
    //执行删除 
    if($this->db->query("DELETE FROM `".$this->tablefix."catagory` WHERE `Lft`>=$Lft AND `Rgt`<=$Rgt")){ 
        $Value=$Rgt-$Lft+1; 
        //更新左右值 
        $this->db->query("UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`-$Value WHERE `Lft`>$Lft"); 
        $this->db->query("UPDATE `".$this->tablefix."catagory` SET `Rgt`=`Rgt`-$Value WHERE `Rgt`>$Rgt"); 
        //$this->referto("成功删除类别","javascript:history.back(1)",3); 
        return 1; 
        }else{ 
        //$this->referto("删除类别失败了","javascript:history.back(1)",3); 
        return -1; 
        } 
    } // end func


        


    /** 
        * Short description. 
        * 1,所有子类,不包含自己;2包含自己的所有子类;3不包含自己所有父类4;包含自己所有父类 
        * Detail description 
        * @param         none 
        * @global         none 
        * @since         1.0 
        * @access         private 
        * @return         void 
        * @update         date time 
    */ 
    function getcatagory($CatagoryID,$type=1) 

    $Result=$this->checkcatagory($CatagoryID); 
    $Lft=$Result['Lft']; 
    $Rgt=$Result['Rgt']; 
    $SeekSQL="SELECT * FROM `".$this->tablefix."catagory` WHERE "; 
    switch ($type) { 
         case "1": 
        $condition="`Lft`>$Lft AND `Rgt`<$Rgt"; 
        break; 
        case "2": 
        $condition="`Lft`>=$Lft AND `Rgt`<=$Rgt"; 
        break; 
         case "3": 
             $condition="`Lft`<$Lft AND `Rgt`>$Rgt"; 
             break; 
        case "4": 
        $condition="`Lft`<=$Lft AND `Rgt`>=$Rgt"; 
        break; 
        default : 
        $condition="`Lft`>$Lft AND `Rgt`<$Rgt"; 
        ; 
        } 
    $SeekSQL.=$condition." ORDER BY `Lft` ASC"; 
    $Sorts=$this->db->getrows($SeekSQL); 
    return $Sorts; 
    } // end func

    /** 
        * Short description. 
        * 取得直属父类 
        * Detail description 
        * @param         none 
        * @global         none 
        * @since         1.0 
        * @access         private 
        * @return         void 
        * @update         date time 
    */ 
    function getparent($CatagoryID) 

    $Parent=$this->getcatagory($CatagoryID,3); 
    return $Parent; 
    } // end func 
    /** 
        * Short description. 
        * 移动类,如果类有子类也一并移动 
        * Detail description 
        * @param         none 
        * @global         none 
        * @since         1.0 
        * @access         private 
        * @return         void 
        * @update         date time 
    */ 
    function movecatagory($SelfCatagoryID,$ParentCatagoryID) 

    $SelfCatagory=$this->checkcatagory($SelfCatagoryID); 
    $NewCatagory=$this->checkcatagory($ParentCatagoryID);


    $SelfLft=$SelfCatagory['Lft']; 
    $SelfRgt=$SelfCatagory['Rgt']; 
    $Value=$SelfRgt-$SelfLft; 
    //取得所有分类的ID方便更新左右值 
    $CatagoryIDS=$this->getcatagory($SelfCatagoryID,2); 
    foreach($CatagoryIDS as $v){ 
        $IDS[]=$v['CatagoryID']; 
        } 
    $InIDS=implode(",",$IDS);


    $ParentLft=$NewCatagory['Lft']; 
    $ParentRgt=$NewCatagory['Rgt']; 
    //print_r($InIDS); 
    //print_r($NewCatagory); 
    //print_r($SelfCatagory); 
    //exit; 
    if($ParentRgt>$SelfRgt){ 
        $UpdateLeftSQL="UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`-$Value-1 WHERE `Lft`>$SelfRgt AND `Rgt`<=$ParentRgt"; 
        $UpdateRightSQL="UPDATE `".$this->tablefix."catagory` SET `Rgt`=`Rgt`-$Value-1 WHERE `Rgt`>$SelfRgt AND `Rgt`<$ParentRgt"; 
        $TmpValue=$ParentRgt-$SelfRgt-1; 
        $UpdateSelfSQL="UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`+$TmpValue,`Rgt`=`Rgt`+$TmpValue WHERE `CatagoryID` IN($InIDS)"; 
        }else{ 
        $UpdateLeftSQL="UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`+$Value+1 WHERE `Lft`>$ParentRgt AND `Lft`<$SelfLft"; 
        $UpdateRightSQL="UPDATE `".$this->tablefix."catagory` SET `Rgt`=`Rgt`+$Value+1 WHERE `Rgt`>=$ParentRgt AND `Rgt`<$SelfLft"; 
        $TmpValue=$SelfLft-$ParentRgt; 
        $UpdateSelfSQL="UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`-$TmpValue,`Rgt`=`Rgt`-$TmpValue WHERE `CatagoryID` IN($InIDS)"; 
        } 
    $this->db->query($UpdateLeftSQL); 
    $this->db->query($UpdateRightSQL); 
    $this->db->query($UpdateSelfSQL); 
    //$this->referto("成功移动类别","javascript:history.back(1)",3); 
    return 1; 
    } // end func


    /** 
        * Short description. 
        * 
        * Detail description 
        * @param         none 
        * @global         none 
        * @since         1.0 
        * @access         private 
        * @return         void 
        * @update         date time 
    */ 
    function checkcatagory($CatagoryID) 

    //检测父类ID是否存在 
    $SQL="SELECT * FROM `".$this->tablefix."catagory` WHERE `CatagoryID`='$CatagoryID' LIMIT 1"; 
    $Result=$this->db->getrow($SQL); 
    if(count($Result)<1){ 
        $this->referto("父类ID不存在,请检查","javascript:history.back(1)",3); 
        } 
    return $Result;      
    } // end func


    /** 
        * Short description. 
        * 
        * Detail description 
        * @param         none 
        * @global         none 
        * @since         1.0 
        * @access         private 
        * @return         array($Catagoryarray,$Deep) 
        * @update         date time 
    */ 
    function sort2array($CatagoryID=0) 

         $Output = array(); 
         if($CatagoryID==0){ 
        $CatagoryID=$this->getrootid(); 
        } 
         if(empty($CatagoryID)){ 
        return array(); 
        exit; 
        } 
         $Result = $this->db->query('SELECT Lft, Rgt FROM `'.$this->tablefix. 
                                     'catagory` WHERE `CatagoryID`='.$CatagoryID); 
         if($Row = $this->db->fetch_array($Result)) { 
         $Right = array(); 
         $Query = 'SELECT * FROM `'.$this->tablefix. 
                     'catagory` WHERE Lft BETWEEN '.$Row['Lft'].' AND '. 
                     $Row['Rgt'].' ORDER BY Lft ASC'; 
          
         $Result = $this->db->query($Query); 
         while ($Row = $this->db->fetch_array($Result)) { 
             if (count($Right)>0) { 
        while ($Right[count($Right)-1]<$Row['Rgt']) { 
        array_pop($Right); 
        } 
             } 
        $Output[]=array('Sort'=>$Row,'Deep'=>count($Right)); 
         $Right[] = $Row['Rgt']; 
         } 
         } 
         return $Output;      
    } // end func

    /** 
        * Short description. 
        * 
        * Detail description 
        * @param         none 
        * @global         none 
        * @since         1.0 
        * @access         private 
        * @return         void 
        * @update         date time 
    */ 
    function getrootid() 

    $Query="SELECT * FROM`".$this->tablefix."catagory` ORDER BY `Lft` ASC LIMIT 1"; 
    $RootID=$this->db->getrow($Query); 
    if(count($RootID)>0){ 
        return $RootID['CatagoryID']; 
        }else{ 288104151
        return 0; 
        } 
    } // end func


    /** 
        * Short description. 
        * 
        * Detail description 
        * @param         none 
        * @global         none 
        * @since         1.0 
        * @access         private 
        * @return         void 
        * @update         date time 
    */ 
    function referto($msg,$url,$sec) 

        echo "<meta http-equiv="Content-Type" content="text/html; charset=utf-8">"; 
        echo "<meta http-equiv=refresh content=$sec;URL=$url>"; 
             if(is_array($msg)){ 
        foreach($msg as $key=>$value){ 
        echo $key."=>".$value."<br>"; 
                 } 
                 }else{ 
                 echo $msg; 
                 } 
         exit; 
    } // end func 
    } // end class


    ?>

    函数描述及例子

    PHP无限分类[左右值]算法

  • 相关阅读:
    学习心得——王梦茹
    优秀学生专栏——孙珩发
    优秀学生专栏——孙振涛
    学习心得——李嫣然、逯广捷
    Spring和Hibernate集成声明式事务 小强斋
    Hibernate——编程式事务 小强斋
    设计模式>原则 小强斋
    Spring>JDK动态代理和CGLIB字节码生成 小强斋
    Hibernate——编程式事务 小强斋
    设计模式>原则 小强斋
  • 原文地址:https://www.cnblogs.com/cbryge/p/6015347.html
Copyright © 2011-2022 走看看