This article mainly introduces the re-understanding of PHP reference, has a certain reference value, now share to everyone, the need for friends can refer to
Cause:
In daily development, we will meet the requirements of the construction tree, construct a tree structure through the relationship of Id,pid, and then traverse the tree. There are two ways to implement it: 1. Recursion, 2. References
The pros and cons of these two methods are also obvious.
Recursive implementation is easier, but with the increase of data volume, its performance is very low.
The concept of reference itself good understanding, performance is also very good, but with good it still exists a certain threshold, not very good writing.
The reason for writing this article is that I have had a very good solution these days and let me re-understand the references. Through this article, summed up their own learning results. OK, that's straight on the code.
Practise
If the following code, you can understand after reading, that you quote really learned to get home, you can also skip this article ha ~.
function Buildtreebyreference ($data, $id = ' id ', $pid = ' pid ', $child = ' children ') { $tmp = [];//with ID-health, $value-value Container, can be very clever to judge the root node element $tree = []; Use references to manipulate the $data data foreach ($data as $key = & $value) { // $tmp [$value [' id ']] = & $value; if (!isset ($tmp [$value [' pid]]) { $tree [] = & $tmp [$value [' id ']; } else { $temp = & $tmp [$value [' pid ']; $temp [$child] = & $value; } Unset ($temp, $value); } return $tree; }
OK, first of all, do not say anything else, you first take the following data to test this method.
$data = [ ["id" = + 1, "pid" = + 0, "name" = "Universe"], ["id" = 2, "pid" = 1, "name" = "Ear" Th '], ["id" = 3, "pid" = + 2, "name" = "China"], ["id" = 4, "pid" = 3, "name" = ' Beijing '] ,];
Add: This method needs to be noted that it requires the parent node to be in front, not suitable for unordered data, so if it is unordered, sort first.
If there is no accident, the printed result should be as follows:
Array (1) { [0]=> Array (4) { ["id"]=> int (1) ["pid"]=> int (0) ["Name"]=> string (8) "Universe" ["Children"]=> Array (1) { [0]=> Array (4) { ["id"]=> int (2) ["pid"]=> Int (1) ["Name"]=> string (5) "Earth" ["Children"]=> Array (1) { [0]=> Array (4) { [" ID "]=> int (3) [" pid "]=> int (2) [" Name "]=> string (5)" China " [" Children "] = = Array (1) { [0]=> Array (3) { ["id"]=> int (4) ["pid"]=> int (3) ["Name"]=> string (7) "Beijing" } }}} }}
If this is the case, you still want to not understand, it's OK, we hit analysis.
In fact, to fully understand this solution, you need to understand two parts.
foreach Assignment principle
The principle of reference
foreach
$data = ["Student", "teacher"]; foreach ($data as $index = + $item) { }
Note that each time you loop, copy the "value" of $data[0] and $data[1] and assign it to the $item
Reference (
Be sure to experiment with your own hands )
$a = 1; $b = & $a; $c = $b; $c = 2; guess $b =?;
If the quote is in doubt, point me
In this case, if you can understand the above foreach and reference, and understand all the execution of the solution, then congratulations, you are very good at learning! But if it is still difficult, it's okay, let's step-by-step.
Analysis
OK, take a deep breath, follow my train of thought, let's step-by-step.
First, let's look at the original function.
function Buildtreebyreference ($data, $id = ' id ', $pid = ' pid ', $child = ' children ') {$tmp = []; #以id为健, $value is a value Container, can be very clever to judge the root node element $tree = []; #利用引用, operate the $data data foreach ($data as $key = & $value) {#& $value fetch to $data yuan Reference $tmp [$value [' id ']] = & $value; #以 $value [' ID '] is the key,& $value reference is a value of push to $tmp, #这样可以巧妙的判断当前元素是否为根节点 if (!isset ( $tmp [$value [' pid ']]) {#将根节点push到 $tree $tree [] = & $tmp [$value [' id ']]; }else {#若当前元素的父节点存在于 $tmp, reference gets the value of the corresponding parent node in $tmp $temp = & amp; $tmp [$value [' PID ']; #然后将当前元素push到其父节点的children中 $temp [$child] = & $value; #为了不引起变量污染, after the use of the reference, you need to unset off unset ($temp, $value); } return $tree; }
First cycle
function Buildtreebyreference ($data, $id = ' id ', $pid = ' pid ', $child = "Children") { # $tmp = []; # $tree = []; # foreach ($data as $key = & $value) { // $tmp [$value [' id ']] = & $value; if (!isset ($tmp [$value [' pid]]) { $tree [] = & $tmp [$value [' id ']; } else { # $temp = & $tmp [$value [' pid ']; # $temp [$child] = & $value; # } unset ($temp, $value); } return $tree; }
Variable condition:
$data [0] = ["id" + 1, "pid" = 0, "name" = "Universe");
$tmp [1] = & $data [0];
$tree [] = & $data [0]
Second cycle
function Buildtreebyreference ($data, $id = ' id ', $pid = ' pid ', $child = "Children") { # $tmp = []; # $tree = []; # foreach ($data as $key = & $value) { // $tmp [$value [' id ']] = & $value; # if (!isset ($tmp [$value [' pid ']]) { # $tree [] = & $tmp [$value [' id ']; } else { $temp = & $tmp [$value [' pid ']; $temp [$child] = & $value; } Unset ($temp, $value); } return $tree; }
Variable condition:
$data [1] = ["id" + 2, "pid" = 1, "name" = "Earth"];
$value =& $data [1];
$tmp [2] = & $data [1];
Attention:
$temp i.e. & $tmp [1], i.e., and $data[0] point to the same address
So $temp[' children ' [] = & $value, the result of the operation is:
$data [ [ "id" = 1, "pid" = 0, "name" = ' Universe ' "Children" =>[ & $data [1] , //Note: stored references ] ] ...]
4. Third Cycle
function Buildtreebyreference ($data, $id = ' id ', $pid = ' pid ', $child = "Children") { # $tmp = []; # $tree = []; # foreach ($data as $key = & $value) { // $tmp [$value [' id ']] = & $value; # if (!isset ($tmp [$value [' pid ']]) { # $tree [] = & $tmp [$value [' id ']; } else { $temp = & $tmp [$value [' pid ']; $temp [$child] = & $value; } Unset ($temp, $value); } return $tree; }
Variable condition:
$data [2] = ["id" + 3, "pid" = 2, "name" = "China"];
$value = & $data [2];
$tmp [3] = & $data [2];
Attention:
$temp i.e. & $tmp [2], i.e., and $data[1] point to the same address
So $temp[' children ' [] = & $value, the result of the operation is:
Note here:
This is the time of the second loop, the reference to the $data[1] stored in the children
$data [ [ "id" = 1, "pid" = 0, "name" = ' Universe ' "Children" =>[ & $data [1] , //Note: stored references ] ] ...]
The third cycle of the time, is $data[1][' children ' [] = & $value, and $value Point is $data[2]
, so the result is:
$data [ [ "id" = 1, "pid" = 0, "name" = ' Universe ' "Children" =>[ //& $data [ 1], //NOTE: The stored reference [ "id" = + 2, "pid" = 1, "name" = "Earth" "Children" = [ &data[2]//NOTE: The store is a reference ] ] []] ... ]
5. Fourth cycle
function Buildtreebyreference ($data, $id = ' id ', $pid = ' pid ', $child = "Children") { # $tmp = []; # $tree = []; # foreach ($data as $key = & $value) { // $tmp [$value [' id ']] = & $value; # if (!isset ($tmp [$value [' pid ']]) { # $tree [] = & $tmp [$value [' id ']; } else { $temp = & $tmp [$value [' pid ']; $temp [$child] = & $value; } Unset ($temp, $value); } return $tree; }
Variable condition:
$data [3] = ["id" + 4, "pid" = 3, "name" = "Beijing");
$value = & $data [3];
$tmp [3] = & $data [3];
Attention:
$temp i.e. & $tmp [2], i.e., and $data[1] point to the same address
So $temp[' children ' [] = & $value, the result of the operation is:
Note here:
This is a reference to the children stored in the third cycle, $data[2]
$data [ [ "id" = 1, "pid" = 0, "name" = ' Universe ' "Children" =>[ //& $data [ 1], //NOTE: The stored reference [ "id" = + 2, "pid" = 1, "name" = "Earth" "Children" = [ &data[2]//NOTE: The store is a reference ] ] []] ... ]
The fourth cycle of the time, is $data[2][' children ' [] = & $value, and $value Point is $data[3]
, so the result is:
$data [["id" = 1, "pid" = 0, "name" = ' Universe ' "Children" = [//& $data [1],//NOTE: The stored reference ["id" = + 2, "pid" = 1, "name" and "Earth" "Child ren "= [///&DATA[2]//NOTE: The reference is stored [ "id" = 3, "pid" = 2, "Name" = "China" "Children" =>[ & $data [3]; Note: A reference is stored]] ] ]] ] ] ... ]
OK, so far, the entire implementation process has gone through, you understand? :)
By the way, there is another method, also by reference, which I do not analyze, if you understand the above method, the following relatively simple.
public static function BuildTreeByReference1 ($data, $id = ' id ', $pid = ' pid ', $child = ' children ') { $tmp = [];
foreach ($data as $key = + $value) { $tmp [$value [$id]] = $value; } $tree = []; foreach ($tmp as $key = + $value) { if (isset ($tmp [$value [' pid]]) {$tmp [$value [ ' pid ']][' children '] = & $tmp [$key]; } else{ $tree [] = & $tmp [$key]; } } return $tree; }