<?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)){2881064151 
    foreach($msg as $key=>$value){ 
    echo $key."=>".$value."<br>"; 
             } 
             }else{ 
             echo $msg; 
             } 
     exit; 
} // end func 
} // end class

?>

函数描述及例子

PHP无限分类[左右值]算法

php构造函数,引入数据库操作类函数的更多相关文章

  1. asp.net+mysq 数据库操作类

    对数据库操作的使用方法: 1.引入命名空间 2.操作.三四行代码即可完成数据操作.类似于: using System; using System.Data; using System.Text; us ...

  2. net core Webapi基础工程搭建(六)——数据库操作_Part 2

    目录 前言 开始 使用 小结 前言 昨天是写着写着发现,时间不早了,已经养成了晚上下班抽时间看看能写点儿啥的习惯(貌似),今天实在是不想让昨天没做完的事情影响,所以又坐下,沉下心(周末了),开始把数据 ...

  3. net core Webapi基础工程搭建(六)——数据库操作_Part 1

    目录 前言 SqlSugar Service层 BaseService(基类) 小结 前言 后端开发最常打交道的就是数据库了(静态网站靠边),上一篇net core Webapi基础工程搭建(五)-- ...

  4. Java数据库操作学习

    JDBC是java和数据库的连接,是一种规范,提供java程序与数据库的连接接口,使用户不用在意具体的数据库.JDBC类型:类型1-JDBC-ODBC桥类型2-本地API驱动类型3-网络协议驱动类型4 ...

  5. 【第一篇】ASP.NET MVC快速入门之数据库操作(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  6. Android打造属于自己的数据库操作类。

    1.概述 开发Android的同学都知道sdk已经为我们提供了一个SQLiteOpenHelper类来创建和管理SQLite数据库,通过写一个子类去继承它,就可以方便的创建.管理数据库.但是当我们需要 ...

  7. PHP数据库操作:使用ORM

    之前我发了一篇博文PHP数据库操作:从MySQL原生API到PDO,向大家展示PHP是如何使用MySQL原生API.MySQLi面向过程.MySQLi面向对象.PDO操作MySQL数据库的.本文介绍如 ...

  8. PHP中对数据库操作的封装

    在动态网面设计中很多都要涉及到对数据库的操作,但是有时跟据需要而改用其它后台数据库,就需要大量修改程序.这是一件枯燥.费时而且容易出错的功作.其实我们可以用PHP中的类来实现对数据库操作的封装,从而使 ...

  9. iOS学习笔记(十五)——数据库操作(SQLite)

    SQLite (http://www.sqlite.org/docs.html) 是一个轻量级的关系数据库.SQLite最初的设计目标是用于嵌入式系统,它占用资源非常少,在嵌入式设备中,只需要几百K的 ...

随机推荐

  1. glut编译问题 (程序无法运行)

    参考:http://blog.csdn.net/robinjwong/article/details/5636049 error: the procedure entry point _glutini ...

  2. Win7下Event_Log服务4201错误的有效解决方法

    在对Windows7系统进行某些优化或者更改了用户权限之后,会导致Window7系统的“事件查看器”无法启动,显示相关服务没有运行,而对相应服务Windows Event Log进行手动启动的时候,会 ...

  3. 化工厂装箱员(洛谷 P2530)

    题目描述 118号工厂是世界唯一秘密提炼锎的化工厂,由于提炼锎的难度非常高,技术不是十分完善,所以工厂生产的锎成品可能会有3种不同的纯度,A:100%,B:1%,C:0.01%,为了出售方便,必须 ...

  4. 失恋28天-缝补礼物(codevs 2503)

    2503 失恋28天-缝补礼物  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 话说上回他给女孩送 ...

  5. 禁随意改root密码

    lsattr 主要参数如表. -a 显示所有文件和目录,包括以"."为名称开头字符的额外内建,现行目录"."与上层目录"..". -d 显示 ...

  6. Java内存访问重排序笔记

    >>关于重排序 重排序通常是编译器或运行时环境为了优化程序性能而采取的对指令进行重新排序执行的一种手段. 重排序分为两类:编译期重排序和运行期重排序,分别对应编译时和运行时环境. > ...

  7. PHPcms怎么调用二级栏目

    {pc:content action=" siteid="$siteid" order="listorder ASC"}             {l ...

  8. poj 3140(树形dp)

    题目链接:http://poj.org/problem?id=3140 思路:简单树形dp题,dp[u]表示以u为根的子树的人数和. #include<iostream> #include ...

  9. CC2540开发板学习笔记(九)—— BLE协议简介

    一.BLE协议简介 1.协议是什么? 协议是一系列的通信标准,双方需要共同按照这进行正常数据 协议是一系列的通信标准,双方需要共同按照这进行正常数据发射和 接收.协议栈是的具体实现形式,通俗点来理解就 ...

  10. HealthKit开发快速入门教程之HealthKit开发概述简介

    HealthKit开发快速入门教程之HealthKit开发概述简介 2014年6月2日召开的年度开发者大会上,苹果发布了一款新的移动应用平台,可以收集和分析用户的健康数据.该移动应用平台被命名为“He ...