基於左右值的無限分類算法

基於左右值的無限分類算法,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. ?>  
相關文章
相關標籤/搜索