基於左右值的無限分類算法,php,因爲以前採用的遞歸排序無限分類方法感受不是很理想,因而參考了國外同國內的左右值排序相關方法,本身寫了一個基於左右值的無限分類類,歡迎你們測試,另外還有用到一個MySQL操做類,因爲不是原創就不提供了,若是須要的能夠PM我javascript
[php] view plain copyphp
- <?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{
- 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
-
- ?>