Home >Backend Development >PHP Tutorial >PHP无限分类-上下值实现

PHP无限分类-上下值实现

WBOY
WBOYOriginal
2016-06-13 12:28:54904browse

PHP无限分类-左右值实现

包含(移动多个节点;移动单个节点;删除多个节点;删除单个节点;新增节点),另附数据库表结构~有问题可以留言(www.webyang.net)。

?

 一、db sql语句//db used for php无限分类create table tree(    id int(10) not null primary key auto_increment,    name varchar(255) not null,    lft int(10) not null default 0,    rgt int(10) not null default 0,    status int(1) not null default 0,    index lft (`lft`),    index rgt (`rgt`),    index status(`status`))charset utf8;insert into tree value (null,'Food',1,18,0);insert into tree value (null,'Fruit',2,11,0);insert into tree value (null,'Red',3,6,0);insert into tree value (null,'Cherry',4,5,0);insert into tree value (null,'Yellow',7,10,0);insert into tree value (null,'Banana',8,9,0);insert into tree value (null,'Meat',12,17,0);insert into tree value (null,'Beef',13,14,0);insert into tree value (null,'Pork',15,16,0);二、php文件<?phperror_reporting(0);/*                         1 Food 18            +------------------------------+        2 Fruit 11                     12 Meat 17    +-------------+                 +------------+3 Red 6      7 Yellow 10       13 Beef 14   15 Pork 164 Cherry 5    8 Banana 9descendants = (right – left - 1) / 2*//** *用于移动一个节点(包括子节点) [email&#160;protected] array $pdata = array('id'=>主键,'root'=>名称) 二选一 父节点(为空时插入最大的父节点) [email&#160;protected] array $ndata = array('id'=>主键,'root'=>名称) 二选一 下一个兄弟节点(没有兄弟的时候就不用) [email&#160;protected] array $cdata = array('id'=>主键,'root'=>名称) 二选一 当前待移动的节点 */function move_tree_all($pdata=array(),$ndata=array(),$cdata=array()) {    $cid   = $cdata['id'] ? intval($cdata['id']) : '';    $croot = $cdata['root'];    if(!$cid && !$croot) return;    //需自加判断    //1、cdata不能为顶级    //2、cdata不能比$pdata等级高    $adata = get_tree_all($cdata); //获取当前移动节点的所有节点    delete_tree_all($cdata,1); //逻辑删除当前移动节点的所有节点    foreach($adata as $k => $val) {        if($k != 0) {            $pdata = array('root'=>$val['parent']);            insert_tree($pdata,'',$val['name'],1);        } else { //first            insert_tree($pdata,$ndata,$val['name'],1);        }    }}/** *用于移动一个节点(不包括子节点) [email&#160;protected] array $pdata = array('id'=>主键,'root'=>名称) 二选一 父节点(为空时插入最大的父节点) [email&#160;protected] array $ndata = array('id'=>主键,'root'=>名称) 二选一 下一个兄弟节点(没有兄弟的时候就不用) [email&#160;protected] array $cdata = array('id'=>主键,'root'=>名称) 二选一 当前待移动的节点 */function move_tree_item($pdata=array(),$ndata=array(),$cdata=array()) {    $cid   = $cdata['id'] ? intval($cdata['id']) : '';    $croot = $cdata['root'];    if(!$cid && !$croot) return;    //需自加判断    //1、cdata不能为顶级    if(!$croot) {        $sql = "SELECT name from tree where id = $cid";        $result = mysql_query($sql);        $row = mysql_fetch_assoc($result);        $croot = $row['name'];        unset($sql);    }    delete_tree_item($cdata,1);    insert_tree($pdata,$ndata,$croot,1);}/** *用于插入一个节点 [email&#160;protected] array $pdata = array('id'=>主键,'root'=>名称) 二选一 父节点(为空时插入最大的父节点) [email&#160;protected] array $ndata = array('id'=>主键,'root'=>名称) 二选一 下一个兄弟节点(没有兄弟的时候就不用) [email&#160;protected] string $name string 新插入的名称 [email&#160;protected] int $update 默认为空,为1时更新插入 */function insert_tree($pdata=array(),$ndata=array(),$name,$update='') {    if(!$name) return;    $pid   = $pdata['id'] ? intval($pdata['id']) : '';    $proot = $pdata['root'];    $nid   = $ndata['id'] ? intval($ndata['id']) : '';    $nroot = $ndata['root'];    //有父无兄(最小的子节点,父节点的最后一个儿子)    if(($pid || $proot) && !($nid || $nroot)) {        $sql    =  $pid ? "SELECT lft, rgt FROM tree WHERE id = '{$pid}';" : "SELECT lft, rgt FROM tree WHERE name = '{$proot}';";        $result = mysql_query($sql);        $row    = mysql_fetch_assoc($result);        unset($sql);        //新节点        $lft  = $row['rgt'];        $rgt  = $lft+1;        if(!$update) {            $sql  = "insert into tree values (null,'{$name}',$lft,$rgt,0);";            $sql1 = "update tree set rgt = rgt+2 where rgt >= {$row['rgt']}";            $sql2 = "update tree set lft = lft+2 where lft >= {$row['rgt']}";        } else {            $sql  = "update tree set lft=$lft,rgt=$rgt,status=0 where name ='{$name}';";            $sql1 = "update tree set rgt = rgt+2 where status =0 and rgt >= {$row['rgt']}";            $sql2 = "update tree set lft = lft+2 where status =0 and lft >= {$row['rgt']}";        }                mysql_query($sql1);        mysql_query($sql2);        mysql_query($sql); //last add new data    }    //有父有兄    if(($pid || $proot) && ($nid || $nroot)) {        $sql    =  $nid ? "SELECT lft, rgt FROM tree WHERE id = '{$nid}';" : "SELECT lft, rgt FROM tree WHERE name = '{$nroot}';";        $result = mysql_query($sql);        $row    = mysql_fetch_assoc($result);        unset($sql);        //新节点        $lft  = $row['lft'];        $rgt  = $lft+1;        if(!$update) {            $sql  = "insert into tree values (null,'{$name}',$lft,$rgt,0);";            $sql1 = "update tree set rgt = rgt+2 where rgt >= {$row['lft']};";            $sql2 = "update tree set lft = lft+2 where lft >= {$row['lft']};";        } else {            $sql  = "update tree set lft=$lft,rgt=$rgt,status=0 where name ='{$name}';";            $sql1 = "update tree set rgt = rgt+2 where status = 0 and rgt >= {$row['lft']};";            $sql2 = "update tree set lft = lft+2 where status = 0 and lft >= {$row['lft']};";        }        mysql_query($sql1);        mysql_query($sql2);        mysql_query($sql); //last add new data    }    //无父无兄(大佬)    if(!($pid || $proot) && !($nid || $nroot)) {        $sql    =  "SELECT max(`rgt`) as rgt FROM tree;";        $result = mysql_query($sql);        $row    = mysql_fetch_assoc($result);        unset($sql);        //新节点        $lft  = 1;        $rgt  = $row['rgt']+2;        if(!$update) {            $sql  = "insert into tree values (null,'{$name}',$lft,$rgt,0);";            $sql1 = "update tree set rgt = rgt+1";            $sql2 = "update tree set lft = lft+1";        } else {            $sql  = "update tree set lft=$lft,rgt=$rgt,status=0 where name ='{$name}';";            $sql1 = "update tree set rgt = rgt+1 where status = 0";            $sql2 = "update tree set lft = lft+1 where status = 0";        }                mysql_query($sql1);        mysql_query($sql2);        mysql_query($sql); //last add new data    }   }/** *用于删除一个节点(包括子节点) [email&#160;protected] array $data = array('id'=>主键,'root'=>名称) 二选一 [email&#160;protected] int $update 默认为空,为1时逻辑删除 */function delete_tree_all($data,$update='') {    $id   = $data['id'] ? intval($data['id']) : '';    $root = $data['root'];    if(!$id && !$root) return;    $sql    =  $id ? "SELECT lft, rgt FROM tree WHERE id = '{$id}';" : "SELECT lft, rgt FROM tree WHERE name = '{$root}';";    $result = mysql_query($sql);    $row    = mysql_fetch_assoc($result);    unset($sql);    $middle = $row['rgt']-$row['lft']+1;    if(!$update) {        $sql    = "delete from tree where lft BETWEEN '" . $row['lft'] . "' AND '" . $row['rgt'] ."'";        $sql1   = "update tree set rgt = rgt-{$middle} where rgt > {$row['rgt']}";        $sql2   = "update tree set lft = lft-{$middle} where lft > {$row['rgt']}";    } else {        $sql    = "update tree set status = 1 where lft BETWEEN '" . $row['lft'] . "' AND '" . $row['rgt'] ."'";        $sql1   = "update tree set rgt = rgt-{$middle} where status=0 and rgt > {$row['rgt']}";        $sql2   = "update tree set lft = lft-{$middle} where status=0 and lft > {$row['rgt']}";    }        mysql_query($sql);    mysql_query($sql1);    mysql_query($sql2);}/** *用于删除一个节点(不包括子节点) [email&#160;protected] array $data = array('id'=>主键,'root'=>名称) 二选一 [email&#160;protected] int $update 默认为空,为1时逻辑删除 */function delete_tree_item($data,$update='') {    $id   = $data['id'] ? intval($data['id']) : '';    $root = $data['root'];    if(!$id && !$root) return;    $sql    =  $id ? "SELECT id,lft, rgt FROM tree WHERE id = '{$id}';" : "SELECT id,lft, rgt FROM tree WHERE name = '{$root}';";    $result = mysql_query($sql);    $row    = mysql_fetch_assoc($result);    unset($sql);    if(!$update) {        $sql  = "delete from tree where id = {$row['id']};";        $sql1 = "update tree set rgt = rgt-1,lft = lft -1 where lft > {$row['lft']} and rgt < {$row['rgt']}";        $sql2 = "update tree set lft = lft-2 where lft > {$row['rgt']}";        $sql3 = "update tree set rgt = rgt-2 where rgt > {$row['rgt']}";    } else {        $sql  = "update tree set status = 1 where id = {$row['id']};";        $sql1 = "update tree set rgt = rgt-1,lft = lft -1 where status = 0 and lft > {$row['lft']} and rgt < {$row['rgt']}";        $sql2 = "update tree set lft = lft-2 where status = 0 and lft > {$row['rgt']}";        $sql3 = "update tree set rgt = rgt-2 where status = 0 and rgt > {$row['rgt']}";    }        mysql_query($sql);    mysql_query($sql1);    //can do or not do just right,but not do load empty 2 number in middle    mysql_query($sql2);    mysql_query($sql3);}/** *用于获取所有的节点 [email&#160;protected] array $data = array('id'=>主键,'root'=>名称) 二选一 */function get_tree_all($data) {    $id   = $data['id'] ? intval($data['id']) : '';    $root = $data['root'];    if(!$id && !$root) return;    $sql    =  $id ? "SELECT lft, rgt FROM tree WHERE id = '{$id}';" : "SELECT lft, rgt FROM tree WHERE name = '{$root}';";    $result = mysql_query($sql);    $row    = mysql_fetch_assoc($result);    $adata  = array(); //所有数据    $right  = array(); //计数    $prev   = array();    $result = mysql_query("SELECT id,name, lft, rgt FROM tree WHERE lft BETWEEN '" . $row['lft'] . "' AND '" . $row['rgt'] ."' ORDER BY lft ASC ;");    while ($row = mysql_fetch_assoc($result)) {        if (count($right) > 0) {            while ($right[count($right) - 1] < $row['rgt']) { // 检查我们是否应该将节点移出堆栈                array_pop($right);                array_pop($prev);            }        }        $parent  = $prev ? end($prev) : '';        $adata[] = array('id'=>$row['id'],'name'=>$row['name'],'level'=>count($right),'parent'=>$parent);        $right[] = $row['rgt'];        $prev[]  = $row['name'];    }    return $adata;}/** *用于展示分类 [email&#160;protected] array $data = array('id'=>主键,'root'=>名称) 二选一 */function display_tree($data) {    $id   = $data['id'] ? intval($data['id']) : '';    $root = $data['root'];    if(!$id && !$root) return;    $sql    =  $id ? "SELECT lft, rgt FROM tree WHERE id = '{$id}';" : "SELECT lft, rgt FROM tree WHERE name = '{$root}';";    $result = mysql_query($sql);    $row    = mysql_fetch_assoc($result);    $right  = array();    $result = mysql_query("SELECT name, lft, rgt FROM tree WHERE lft BETWEEN '" . $row['lft'] . "' AND '" . $row['rgt'] ."' ORDER BY lft ASC ;");    while ($row = mysql_fetch_assoc($result)) {        if (count($right) > 0) { // 检查我们是否应该将节点移出堆栈            while ($right[count($right) - 1] < $row['rgt']) {                array_pop($right);            }        }        echo str_repeat('  ',count($right)) . $row['name'] . "\n";        $right[] = $row['rgt'];    }}mysql_connect('localhost','root','') or die('connect error');mysql_select_db('test') or die('database error');mysql_query('set names utf8');display_tree(array('root'=>'Food'));//display_tree(array('root'=>'bigboss'));//move_tree_all($pdata=array('root'=>'Fruit'),$ndata=array('root'=>'Red'),$cdata=array('root'=>'Meat'));//move_tree_all('','',$cdata=array('root'=>'Meat'));//move_tree_item('','',array('root'=>'Red'));//move_tree_item(array('root'=>'Red'),array('root'=>'Cherry'),array('root'=>'Fruit'));//delete_tree_all(array('root'=>'Yellow'));//delete_tree_all(array('root'=>'Meat'));//delete_tree_item(array('root'=>'Meat'));//insert_tree('','','bigboss');//insert_tree(array('root'=>'Red'),'','dalao');//insert_tree(array('root'=>'Red'),array('root'=>'Cherry'),'baddalao');//insert_tree(array('root'=>'Fruit'),array('root'=>'Red'),'Redbother');display_tree(array('root'=>'Food'));

?

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn