基于左右值的无限分类算法

基于左右值的无限分类算法,php,因为以前采用的递归排序无限分类方法感受不是很理想,因而参考了国外同国内的左右值排序相关方法,本身写了一个基于左右值的无限分类类,欢迎你们测试,另外还有用到一个MySQL操做类,因为不是原创就不提供了,若是须要的能够PM我javascript

 

[php] view plain copyphp

 

  1. <?php  
  2. /** 
  3.  * 基于左右值排序的无限分类算法 
  4.  * 数据库结果为 
  5. CREATE TABLE om_catagory ( 
  6.     CatagoryID int(10) unsigned NOT NULL auto_increment, 
  7.  Name varchar(50) default '', 
  8.     Lft int(10) unsigned NOT NULL default '0', 
  9.     Rgt int(10) unsigned NOT NULL default '0', 
  10.     PRIMARY KEY (id), 
  11.     KEY lft (lft), 
  12.     KEY rgt (rgt)  
  13.  * 更多的关于左右值排序的例子 
  14.  * http://www.chinaunix.net/jh/27/239532.html(http://dev.mysql.com/tech-resources/articles/hierarchical-data.html) 
  15.  * @author [email]psdshow@yahoo.com.cn[/email]  
  16.  * @version      1.0 
  17.  * @copyright psdshow 
  18.  * 欢迎光临个人我的日志 http://www.dayanmei.com 
  19.  */  
  20. class sortclass  
  21. {  
  22.   
  23. /** 
  24.  * Description 
  25.  * @var        
  26.  * @since     1.0 
  27.  * @access    private 
  28.  */  
  29. var $db;  
  30.   
  31. /** 
  32.  * Description 
  33.  * @var        
  34.  * @since     1.0 
  35.  * @access    private 
  36.  */  
  37. var $tablefix;  
  38.   
  39. /** 
  40.  * Short description.  
  41.  * 构造函数,引入数据库操做类函数 
  42.  * Detail description 
  43.  * @param      none 
  44.  * @global     none 
  45.  * @since      1.0 
  46.  * @access     private 
  47.  * @return     void 
  48.  * @update     date time 
  49. */  
  50. function sortclass()  
  51. {  
  52. global $db;  
  53. $this->db=$db;  
  54. $this->tablefix="om_";  
  55. } // end func  
  56.   
  57. /** 
  58.  * Short description.  
  59.  * 增长新的分类 
  60.  * Detail description 
  61.  * @param      none 
  62.  * @global     none 
  63.  * @since      1.0 
  64.  * @access     private 
  65.  * @return     void 
  66.  * @update     date time 
  67. */  
  68. function addsort($CatagoryID,$SortName)  
  69. {  
  70. if($CatagoryID==0){  
  71.  $Lft=0;  
  72.  $Rgt=1;  
  73.  }else{  
  74.  $Result=$this->checkcatagory($CatagoryID);  
  75.  //取得父类的左值,右值  
  76.  $Lft=$Result['Lft'];  
  77.  $Rgt=$Result['Rgt'];  
  78.  $this->db->query("UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`+2 WHERE `Lft`>$Rgt");  
  79.  $this->db->query("UPDATE `".$this->tablefix."catagory` SET `Rgt`=`Rgt`+2 WHERE `Rgt`>=$Rgt");  
  80.  }  
  81.   
  82. //插入  
  83. if($this->db->query("INSERT INTO `".$this->tablefix."catagory` SET `Lft`='$Rgt',`Rgt`='$Rgt'+1,`Name`='$SortName'")){  
  84.  //$this->referto("成功增长新的类别","JAVASCRIPT:HISTORY.BACK(1)",3);  
  85.  return 1;  
  86.  }else{  
  87.  //$this->referto("增长新的类别失败了","JAVASCRIPT:HISTORY.BACK(1)",3);  
  88.  return -1;  
  89.  }  
  90. } // end func  
  91.   
  92.   
  93. /** 
  94.  * Short description.  
  95.  * 删除类别 
  96.  * Detail description 
  97.  * @param      none 
  98.  * @global     none 
  99.  * @since      1.0 
  100.  * @access     private 
  101.  * @return     void 
  102.  * @update     date time 
  103. */  
  104. function deletesort($CatagoryID)  
  105. {  
  106. //取得被删除类别的左右值,检测是否有子类,若是有就一块儿删除  
  107. $Result=$this->checkcatagory($CatagoryID);  
  108. $Lft=$Result['Lft'];  
  109. $Rgt=$Result['Rgt'];  
  110. //执行删除  
  111. if($this->db->query("DELETE FROM `".$this->tablefix."catagory` WHERE `Lft`>=$Lft AND `Rgt`<=$Rgt")){  
  112.  $Value=$Rgt-$Lft+1;  
  113.  //更新左右值  
  114.  $this->db->query("UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`-$Value WHERE `Lft`>$Lft");  
  115.  $this->db->query("UPDATE `".$this->tablefix."catagory` SET `Rgt`=`Rgt`-$Value WHERE `Rgt`>$Rgt");  
  116.  //$this->referto("成功删除类别","javascript:history.back(1)",3);  
  117.  return 1;  
  118.  }else{  
  119.  //$this->referto("删除类别失败了","javascript:history.back(1)",3);  
  120.  return -1;  
  121.  }  
  122. } // end func  
  123.   
  124.    
  125.   
  126. /** 
  127.  * Short description.  
  128.  * 1,全部子类,不包含本身;2包含本身的全部子类;3不包含本身全部父类4;包含本身全部父类 
  129.  * Detail description 
  130.  * @param      none 
  131.  * @global     none 
  132.  * @since      1.0 
  133.  * @access     private 
  134.  * @return     void 
  135.  * @update     date time 
  136. */  
  137. function getcatagory($CatagoryID,$type=1)  
  138. {  
  139. $Result=$this->checkcatagory($CatagoryID);  
  140. $Lft=$Result['Lft'];  
  141. $Rgt=$Result['Rgt'];  
  142. $SeekSQL="SELECT * FROM `".$this->tablefix."catagory` WHERE ";  
  143. switch ($type) {  
  144.     case "1":  
  145.   $condition="`Lft`>$Lft AND `Rgt`<$Rgt";  
  146.   break;  
  147.  case "2":  
  148.   $condition="`Lft`>=$Lft AND `Rgt`<=$Rgt";  
  149.   break;  
  150.     case "3":  
  151.      $condition="`Lft`<$Lft AND `Rgt`>$Rgt";  
  152.      break;   
  153.  case "4":  
  154.   $condition="`Lft`<=$Lft AND `Rgt`>=$Rgt";  
  155.   break;  
  156.  default :  
  157.   $condition="`Lft`>$Lft AND `Rgt`<$Rgt";  
  158.   ;  
  159.  }   
  160. $SeekSQL.=$condition." ORDER BY `Lft` ASC";  
  161. $Sorts=$this->db->getrows($SeekSQL);  
  162. return $Sorts;  
  163. } // end func  
  164.   
  165.   
  166. /** 
  167.  * Short description.  
  168.  * 取得直属父类 
  169.  * Detail description 
  170.  * @param      none 
  171.  * @global     none 
  172.  * @since      1.0 
  173.  * @access     private 
  174.  * @return     void 
  175.  * @update     date time 
  176. */  
  177. function getparent($CatagoryID)  
  178. {  
  179. $Parent=$this->getcatagory($CatagoryID,3);  
  180. return $Parent;  
  181. } // end func  
  182. /** 
  183.  * Short description.  
  184.  * 移动类,若是类有子类也一并移动 
  185.  * Detail description 
  186.  * @param      none 
  187.  * @global     none 
  188.  * @since      1.0 
  189.  * @access     private 
  190.  * @return     void 
  191.  * @update     date time 
  192. */  
  193. function movecatagory($SelfCatagoryID,$ParentCatagoryID)  
  194. {  
  195. $SelfCatagory=$this->checkcatagory($SelfCatagoryID);  
  196. $NewCatagory=$this->checkcatagory($ParentCatagoryID);  
  197.   
  198. $SelfLft=$SelfCatagory['Lft'];  
  199. $SelfRgt=$SelfCatagory['Rgt'];  
  200. $Value=$SelfRgt-$SelfLft;  
  201. //取得全部分类的ID方便更新左右值  
  202. $CatagoryIDS=$this->getcatagory($SelfCatagoryID,2);  
  203. foreach($CatagoryIDS as $v){  
  204.  $IDS[]=$v['CatagoryID'];  
  205.  }  
  206. $InIDS=implode(",",$IDS);  
  207.   
  208. $ParentLft=$NewCatagory['Lft'];  
  209. $ParentRgt=$NewCatagory['Rgt'];  
  210. //print_r($InIDS);  
  211. //print_r($NewCatagory);  
  212. //print_r($SelfCatagory);  
  213. //exit;  
  214. if($ParentRgt>$SelfRgt){  
  215.  $UpdateLeftSQL="UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`-$Value-1 WHERE `Lft`>$SelfRgt AND `Rgt`<=$ParentRgt";  
  216.  $UpdateRightSQL="UPDATE `".$this->tablefix."catagory` SET `Rgt`=`Rgt`-$Value-1 WHERE `Rgt`>$SelfRgt AND `Rgt`<$ParentRgt";  
  217.  $TmpValue=$ParentRgt-$SelfRgt-1;  
  218.  $UpdateSelfSQL="UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`+$TmpValue,`Rgt`=`Rgt`+$TmpValue WHERE `CatagoryID` IN($InIDS)";  
  219.  }else{  
  220.  $UpdateLeftSQL="UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`+$Value+1 WHERE `Lft`>$ParentRgt AND `Lft`<$SelfLft";  
  221.  $UpdateRightSQL="UPDATE `".$this->tablefix."catagory` SET `Rgt`=`Rgt`+$Value+1 WHERE `Rgt`>=$ParentRgt AND `Rgt`<$SelfLft";  
  222.  $TmpValue=$SelfLft-$ParentRgt;  
  223.  $UpdateSelfSQL="UPDATE `".$this->tablefix."catagory` SET `Lft`=`Lft`-$TmpValue,`Rgt`=`Rgt`-$TmpValue WHERE `CatagoryID` IN($InIDS)";  
  224.  }  
  225. $this->db->query($UpdateLeftSQL);  
  226. $this->db->query($UpdateRightSQL);  
  227. $this->db->query($UpdateSelfSQL);  
  228. //$this->referto("成功移动类别","javascript:history.back(1)",3);  
  229. return 1;  
  230. } // end func  
  231.   
  232. /** 
  233.  * Short description.  
  234.  * 
  235.  * Detail description 
  236.  * @param      none 
  237.  * @global     none 
  238.  * @since      1.0 
  239.  * @access     private 
  240.  * @return     void 
  241.  * @update     date time 
  242. */  
  243. function checkcatagory($CatagoryID)  
  244. {  
  245. //检测父类ID是否存在  
  246. $SQL="SELECT * FROM `".$this->tablefix."catagory` WHERE `CatagoryID`='$CatagoryID' LIMIT 1";  
  247. $Result=$this->db->getrow($SQL);  
  248. if(count($Result)<1){  
  249.  $this->referto("父类ID不存在,请检查","javascript:history.back(1)",3);  
  250.  }  
  251. return $Result;    
  252. } // end func  
  253.   
  254. /** 
  255.  * Short description.  
  256.  * 
  257.  * Detail description 
  258.  * @param      none 
  259.  * @global     none 
  260.  * @since      1.0 
  261.  * @access     private 
  262.  * @return     array($Catagoryarray,$Deep) 
  263.  * @update     date time 
  264. */  
  265. function sort2array($CatagoryID=0)  
  266. {  
  267.   $Output = array();  
  268.   if($CatagoryID==0){  
  269.  $CatagoryID=$this->getrootid();  
  270.  }  
  271.   if(empty($CatagoryID)){  
  272.  return array();  
  273.  exit;  
  274.  }  
  275.   $Result = $this->db->query('SELECT Lft, Rgt FROM `'.$this->tablefix.  
  276.                         'catagory` WHERE `CatagoryID`='.$CatagoryID);   
  277.   if($Row = $this->db->fetch_array($Result)) {  
  278.   $Right = array();   
  279.   $Query = 'SELECT * FROM `'.$this->tablefix.  
  280.              'catagory` WHERE Lft BETWEEN '.$Row['Lft'].' AND '.   
  281.              $Row['Rgt'].' ORDER BY Lft ASC';  
  282.     
  283.   $Result = $this->db->query($Query);   
  284.     while ($Row = $this->db->fetch_array($Result)) {   
  285.       if (count($Right)>0) {   
  286.   while ($Right[count($Right)-1]<$Row['Rgt']) {   
  287.   array_pop($Right);  
  288.   }   
  289.      }  
  290.  $Output[]=array('Sort'=>$Row,'Deep'=>count($Right));  
  291.     $Right[] = $Row['Rgt'];  
  292.     }  
  293.   }  
  294.   return $Output;     
  295. } // end func  
  296.   
  297.   
  298. /** 
  299.  * Short description.  
  300.  * 
  301.  * Detail description 
  302.  * @param      none 
  303.  * @global     none 
  304.  * @since      1.0 
  305.  * @access     private 
  306.  * @return     void 
  307.  * @update     date time 
  308. */  
  309. function getrootid()  
  310. {  
  311. $Query="SELECT * FROM`".$this->tablefix."catagory` ORDER BY `Lft` ASC LIMIT 1";  
  312. $RootID=$this->db->getrow($Query);  
  313. if(count($RootID)>0){  
  314.  return $RootID['CatagoryID'];  
  315.  }else{  
  316.  return 0;  
  317.  }  
  318. } // end func  
  319.   
  320. /** 
  321.  * Short description.  
  322.  * 
  323.  * Detail description 
  324.  * @param      none 
  325.  * @global     none 
  326.  * @since      1.0 
  327.  * @access     private 
  328.  * @return     void 
  329.  * @update     date time 
  330. */  
  331. function referto($msg,$url,$sec)  
  332. {  
  333.  echo "<meta http-equiv="Content-Type" content="text/html; charset=utf-8">";  
  334.  echo "<meta http-equiv=refresh content=$sec;URL=$url>";  
  335.    if(is_array($msg)){  
  336.  foreach($msg as $key=>$value){  
  337.   echo $key."=>".$value."<br>";  
  338.         }  
  339.         }else{  
  340.         echo $msg;  
  341.         }  
  342.    exit;  
  343. } // end func  
  344. } // end class  
  345.   
  346. ?>  
相关文章
相关标签/搜索