Unlimited classification of left and right values of thinkphp

Source: Internet
Author: User
This article provides a detailed analysis of the infinite left and right values of thinkphp. For more information, see

This article provides a detailed analysis of the infinite left and right values of thinkphp. For more information, see

I used to use unlimited parent-child classification. This classification structure is clear and easy to use. However, if the number of categories is large, the query performance is poor. For example, in the navigation menu, I want to query the entire category tree based on a specific category (ancestor ).
The performance consumption is very high. Hong Kong virtual hosts either do recursion or perform multiple queries. Therefore, we recommend that you use left and right values when the data volume of a category is large to reduce query troubles.

The Code is as follows:


_ Id
/**
+ ----------------------------------------------------------
* Constructor
* @ Access public
* @ Return void
+ ----------------------------------------------------------
*/
Public function _ construct ($ left, $ right, $ id ){
Parent: :__ construct ();
$ This-> _ left = $ left;
$ This-> _ right = $ right;
$ This-> _ id = $ id;
}
/**
+ ----------------------------------------------------------
* Get all node values based on node $ this-> _ id.
* @ Access public
* @ Param $ nodeId
* @ Return array
+ ----------------------------------------------------------
*/
Public function getNodeById ($ nodeId)
{
If ($ nodeId> 0)
{
Return $ this-> getById ($ nodeId );
}
Else
{
Throw_exception ('unknown $ this-> _ id ');
Return false;
}
}
/**
+ ----------------------------------------------------------
* Obtain the parent node, including the parent class (type = 1). All parent classes: type = 0
* @ Access public
* @ Param $ nodeId int node $ this-> _ id
* @ Return $ parentNode array ()
+ ----------------------------------------------------------
*/
Public function getParentNode ($ nodeId, $ type = 0)
{
If ($ nodeId = 0) throw_exception ('unknown $ this-> _ id ');;
$ CurrentNode = $ this-> getNodeById ($ nodeId );
If ($ currentNode)
{
$ Condition = "". $ this-> _ left. '<'. $ currentNode [$ this-> _ left]. and '. $ this-> _ right. '> '. $ currentNode [$ this-> _ right]. "";
If ($ type = 1) // directly parent class
{
Return $ this-> where ($ condition)-> order ($ this-> _ left. "DESC")-> limit (1)-> find ();
// $ SQL = "SELECT * FROM". TABLE_NAME. "WHERE {$ condition} ORDER BY". $ this-> _ left. "DESC LIMIT 1 ";
// Return mysql_query ($ SQL) or die (mysql_error ());
}
Else if ($ type = 0)
{
Return $ this-> where ($ condition)-> findAll ();
// $ SQL = "SELECT * FROM". TABLE_NAME. "WHERE {$ condition }";
// Return mysql_query ($ SQL) or die (mysql_error ());
}
}
Else
{
Return false;
}
}
/**
+ ----------------------------------------------------------
* Total number of child nodes under the current node. Total number of children = (right value of the current node-left value of the current node-1)/2
* @ Access public
* @ Param $ node_id int node $ this-> _ id
* @ Return $ amount int Total Number of Children under this node *
+ ----------------------------------------------------------
*/
Public function getChildCount ($ nodeId)
{
$ CurrentNode = $ this-> getNodeById ($ nodeId );
If (! Empty ($ currentNode ))
{
Return (int) ($ currentNode [$ this-> _ right]-$ currentNode [$ this-> _ left]-1)/2;
}
}
/**
+ ----------------------------------------------------------
* Obtain all subnodes under the current node. When the right node of subclass A = the left node of subclass B-1, A and B belong to the same level
* @ Access public
* @ Param $ curentId
* @ Param $ type int 0: All subclasses under the current node. 1 is the first subclass of the current node.
* @ Return bool
+ ----------------------------------------------------------
*/
Public function getChild ($ nodeId, $ type = 0)
{
$ CurrentNode = $ this-> getNodeById ($ nodeId );
If ($ currentNode [$ this-> _ left]-$ currentNode [$ this-> _ right] = 1)
{
Return false; // when the left-right value of the node is 1, no subnodes exist.
}
Else
{
$ Condition = $ this-> _ left. '> '. $ currentNode [$ this-> _ left]. and '. $ this-> _ right. '<'. $ currentNode [$ this-> _ right];
$ Child = $ this-> where ($ condition)-> findAll ();
If ($ type = 0) // All subclasses
{
Return $ child;
}
Else if ($ type = 1) // obtain the next level of the current node.
{
$ SubArr = array (); // first-level subclass
Foreach ($ child as $ k => $ sub ){
// The left node of the subclass = the left node + 1 of the parent class, then the subclass is the first subclass
If ($ sub [$ this-> _ left] = $ currentNode [$ this-> _ left] + 1)
{
// $ Right = $ sub [$ k] [$ this-> _ right]; // The right node of the current node
$ FirstSub = $ sub; // The first subclass of the current node
Array_push ($ subArr, $ firstSub); // subclass inbound Stack
Unset ($ child [$ k]);
}
}
$ RightVal = $ firstSub [$ this-> _ right]; // The first subnode is a comparison flag.
$ ChildCount = count ($ child); // number of remaining child nodes
For ($ I = 0; $ I <$ childCount; $ I ++) // cyclically retrieves sub-nodes of the same level
{
Foreach ($ child as $ key => $ sub2 ){
If ($ rightVal ==$ sub2 [$ this-> _ left]-1)
{
$ RightVal = $ sub2 [$ this-> _ right]; // compare the right node of the current node.
Array_push ($ subArr, $ sub2 );
Unset ($ child [$ key]);
}
}
}
Return $ subArr;
}
}
}
/**
+ ----------------------------------------------------------
* Returns the complete path of the current node.
* @ Access public
* @ Param $ nodeId
* @ Return array
+ ----------------------------------------------------------
*/
Public function getSinglePath ($ nodeId)
{
$ SQL = "select parent. * from _ TABLE _ as node ,__ TABLE _ as parent where node. {$ this-> _ left} between parent. {$ this-> _ left}
AND parent. {$ this-> _ right} AND node. {$ this-> _ id }={ $ nodeId} order by parent. {$ this-> _ left }";
// Echo $ SQL;
Return $ this-> query ($ SQL );
}
/**
+ ----------------------------------------------------------
* Add a subnode. There are three types: 0: append a subnode to the current node; 1: append the first subnode to the current node;


2: append after a subnode under the current node

The Code is as follows:

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.