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

基于左右值的无限分类算法,php,由于之前采用的递归排序无限分类方法感觉不是很理想,于是参考了国外同国内的左右值排序相关方法,自己写了一个基于左右值的无限分类类,欢迎大家测试,另外还有用到一个MySQL操作类,由于不是原创就不提供了,如果需要的可以PM我

 

[php] view plain copy

 

  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. ?>  

转载于:https://my.oschina.net/u/588516/blog/744720

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值