基于左右值的无限分类,php,由于之前采用的递归排序无限分类方法感觉不是很理想,于是参考了国外同国内的左右值排序相关方法,自己写了一个基于左右值的无限分类类,欢迎大家测试,另外还有用到一个操作类,由于不是原创就不提供了,如果需要的可以PM我
[php]
- <?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)
- * [email]psdshow@yahoo.com.cn[/email]
- * 1.0
- * psdshow
- * 欢迎光临我的个人日志 http://www.dayanmei.com
- */
- class sortclass
- {
- /**
- * Description
- *
- * @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
- ?>