Unlimited classification is often used in column classification. Today we will look at an example of PHP unlimited classification using left and right values. I hope this example will help you. Unlimited classification is often used in column classification. Today we will look at an example of PHP unlimited classification using left and right values. I hope this example will help you.
Script ec (2); script
I. db SQL statements
// Db used for php unlimited Classification
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', 0 );
Insert into tree value (null, 'fruit', 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 );
Ii. php file
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
*/
/**
* Used to move a node (including subnodes)
* @ Param array $ pdata = array ('id' => Primary Key, 'root' => name) Select a parent node (insert the largest parent node when it is null)
* @ Param array $ ndata = array ('id' => Primary Key, 'root' => name) Select a sibling node (not required if there are no siblings)
* @ Param array $ cdata = array ('id' => Primary Key, 'root' => name) Select the node to be moved.
*/
Function move_tree_all ($ pdata = array (), $ ndata = array (), $ cdata = array ()){
$ Cid = $ cdata ['id']? Intval ($ cdata ['id']): '';
$ Croot = $ cdata ['root'];
If (! $ Cid &&! $ Croot) return;
// Self-increment judgment required
// 1. The cdata cannot be top-level
// 2. cdata cannot be of a higher level than $ pdata
$ Adata = get_tree_all ($ cdata); // retrieve all nodes of the current mobile node
Delete_tree_all ($ cdata, 1); // logically delete all nodes of the current mobile node
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 );
}
}
}
/**
* Used to move a node (excluding subnodes)
* @ Param array $ pdata = array ('id' => Primary Key, 'root' => name) Select a parent node (insert the largest parent node when it is null)
* @ Param array $ ndata = array ('id' => Primary Key, 'root' => name) Select a sibling node (not required if there are no siblings)
* @ Param array $ cdata = array ('id' => Primary Key, 'root' => name) Select the node to be moved.
*/
Function move_tree_item ($ pdata = array (), $ ndata = array (), $ cdata = array ()){
$ Cid = $ cdata ['id']? Intval ($ cdata ['id']): '';
$ Croot = $ cdata ['root'];
If (! $ Cid &&! $ Croot) return;
// Self-increment judgment required
// 1. The cdata cannot be top-level
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 );
}
/**
* Used to insert a node
* @ Param array $ pdata = array ('id' => Primary Key, 'root' => name) Select a parent node (insert the largest parent node when it is null)
* @ Param array $ ndata = array ('id' => Primary Key, 'root' => name) Select a sibling node (not required if there are no siblings)
* @ Param string $ name string newly inserted name
* @ Param int $ update is empty by default. If it is set to 1, update and insert.
*/
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'];
// Has a parent and a brother (the smallest child node, the last son of the parent node)
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 );
// New node
$ 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
}
// Has a parent and a brother
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 );
// New node
$ 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
}
// No father, no brother (daxie)
If (! ($ Pid | $ proot )&&! ($ Nid | $ nroot )){
$ SQL = "SELECT max ('rgt ') as rgt FROM tree ;";
$ Result = mysql_query ($ SQL );
$ Row = mysql_fetch_assoc ($ result );
Unset ($ SQL );
// New node
$ 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
}
}
/**
* Used to delete a node (including subnodes)
* @ Param array $ data = array ('id' => Primary Key, 'root' => name) either
* @ Param int $ update is empty by default. If it is set to 1, it is logically deleted.
*/
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 '". $ 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 );
}
/**
* Used to delete a node (excluding subnodes)
* @ Param array $ data = array ('id' => Primary Key, 'root' => name) either
* @ Param int $ update is empty by default. If it is set to 1, it is logically deleted.
*/
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 );
}
/**
* Used to retrieve all nodes
* @ Param array $ data = array ('id' => Primary Key, 'root' => name) either
*/
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 (); // all data
$ Right = array (); // count
$ Prev = array ();
$ Result = mysql_query ("SELECT id, name, lft, rgt FROM tree WHERE lft '". $ 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 ']) {// check whether the node should be removed from the stack
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;
}
/**
* Used to display categories
* @ Param array $ data = array ('id' => Primary Key, 'root' => name) either
*/
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 '". $ row ['lft ']. "'AND '". $ row ['rgt ']. "'order BY lft ASC ;");
While ($ row = mysql_fetch_assoc ($ result )){
If (count ($ right)> 0) {// check whether we should remove the node from the stack
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' => 'bigbos '));
// 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' => 'failed'), array ('root' => 'red'), 'redbother ');
Display_tree (array ('root' => 'food '));