cari
Rumahphp教程PHP源码左右值实现PHP无限分类例子

无限分类在栏目分类中我们经常会用到了,今天来看一个使用左右值实现PHP无限分类例子了,希望这个例子可以对各位带来帮助。

<script>ec(2);</script>


一、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文件

error_reporting(0);
/*
                         1 Food 18
            +------------------------------+
        2 Fruit 11                     12 Meat 17
    +-------------+                 +------------+
3 Red 6      7 Yellow 10       13 Beef 14   15 Pork 16
4 Cherry 5    8 Banana 9

descendants = (right – left - 1) / 2
*/

/**
 *用于移动一个节点(包括子节点)
 *@param array $pdata = array('id'=>主键,'root'=>名称) 二选一 父节点(为空时插入最大的父节点)
 *@param array $ndata = array('id'=>主键,'root'=>名称) 二选一 下一个兄弟节点(没有兄弟的时候就不用)
 *@param 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);
        }
    }
}

/**
 *用于移动一个节点(不包括子节点)
 *@param array $pdata = array('id'=>主键,'root'=>名称) 二选一 父节点(为空时插入最大的父节点)
 *@param array $ndata = array('id'=>主键,'root'=>名称) 二选一 下一个兄弟节点(没有兄弟的时候就不用)
 *@param 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);
}

/**
 *用于插入一个节点
 *@param array $pdata = array('id'=>主键,'root'=>名称) 二选一 父节点(为空时插入最大的父节点)
 *@param array $ndata = array('id'=>主键,'root'=>名称) 二选一 下一个兄弟节点(没有兄弟的时候就不用)
 *@param string $name string 新插入的名称
 *@param 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
    }
  
}

/**
 *用于删除一个节点(包括子节点)
 *@param array $data = array('id'=>主键,'root'=>名称) 二选一
 *@param 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);
}

/**
 *用于删除一个节点(不包括子节点)
 *@param array $data = array('id'=>主键,'root'=>名称) 二选一
 *@param 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         $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         $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);
}

/**
 *用于获取所有的节点
 *@param 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]                 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;
}

/**
 *用于展示分类
 *@param 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]                 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'));

Kenyataan
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
1 bulan yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
1 bulan yang laluBy尊渡假赌尊渡假赌尊渡假赌
Akan R.E.P.O. Ada Crossplay?
1 bulan yang laluBy尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

SecLists

SecLists

SecLists ialah rakan penguji keselamatan muktamad. Ia ialah koleksi pelbagai jenis senarai yang kerap digunakan semasa penilaian keselamatan, semuanya di satu tempat. SecLists membantu menjadikan ujian keselamatan lebih cekap dan produktif dengan menyediakan semua senarai yang mungkin diperlukan oleh penguji keselamatan dengan mudah. Jenis senarai termasuk nama pengguna, kata laluan, URL, muatan kabur, corak data sensitif, cangkerang web dan banyak lagi. Penguji hanya boleh menarik repositori ini ke mesin ujian baharu dan dia akan mempunyai akses kepada setiap jenis senarai yang dia perlukan.

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Persekitaran pembangunan bersepadu PHP yang berkuasa