Make hierarchy in PHP array in loop

I have been struggling with such a problem for so many hours. To speed up my webpage, I query the database to get all categories just once, and then I want to sort the array using PHP.

Array ( [0] => Array ( [id] => 1 [name] => name1 [parent] => 0 [children] => ) [1] => Array ( [id] => 2 [name] => name2 [parent] => 1 [children] => ) ) 

I need to get something like this

 Array ( [0] => Array ( [id] => 1 [name] => name1 [parent] => 0 [children] => Array ( [id] => 2 [name] => name2 [parent] => 1 [children] => ) ) ) 

The problem with this is to make it for any level of the hierarchy. So that he can work in a cycle. Please, help!

+4
source share
5 answers

There are many solutions to reduce overhead. But, not knowing what your limitations are, it's hard to recommend an approach.

eg:.

  • use adjacency model - see my comment on dnagirl answer

  • load all the data into PHP and then use the recursion algorithm to create a nested tree (this will be pretty slow and will benefit from some caching)

  • write a recursive stored procedure that returns a result set sorted by tree of depth tree

Example 2 is a bit closer to the code .... something like ....

  function build_tree(&$unsorted, $start_node) { $out=array(); foreach($unsorted as $key=>$node) { if ($node['parent']==$start_node) { $node['children']=build_tree($unsorted, $key); unset($unsorted[$key]); $out[]=$node; } } return $out; } $threaded_tree=build_tree($list_of_nodes, 0); // assumes that the root is the first element 
+4
source
 foreach ($dataFromMySQL as $e) { $all[$e['id']] = $e; $ref = &$all[$e['id']; if ($e['parent']) $all[$e['id']]['children'][] = $ref; else $hierarchy[$e['id']] = $ref; } 

This suggests that parents will always be settled in front of their children.

0
source

You use the adjacency model for your hierarchy. You will have to either request your db several times, or if the number of levels is known, build a join request with a proposal for each level.

If allowed, you will most likely find that the AJAX solution, where the child levels are called when the parent clicks, is easier to program and more efficient.

0
source

What you are looking for is called recursion, since it is not very clear to me how to handle recursions in php, and the documentation is almost empty regarding this question.

You may be interested in checking out this and this article.

0
source

Not sure if you have found the answer yet, but today I was looking for the same solution and finally decided to create my own solution. The code below is the class I just created, and it works with arrays and PHP objects and is recursive for an unlimited number of dimensions.

GitHub https://github.com/DukeOfMarshall/PHP-Array-Heirarchy-Display

A simple example of using this code would be:

 <?php require_once('Arrays.class.php'); $display = new Array_Functions(); $display->display_hierarchy($multidimensional_array); ?> 

There are other parameters that can be set as well, but it was just a direct hierarchical display of an array or object.

 <?php class Array_Functions { public $number_of_tabs = 3; # The default number of tabs to use when branching out private $counter = 0; # The counter to use for the number of tab iterations to use on the current branch public $display_square_brackets = TRUE; public $display_squiggly_brackets = FALSE; public $display_parenthesis = FALSE; public $display_apostrophe = TRUE; public $display_quotes = FALSE; public function __construct(){ } /** * Displays the array in an organized heirarchy and even does so recursively * * $array ARRAY - The array to display in a heirarchy * * $key_bookends STRING - The character to place on either side of the array key when printed * @@ square - Displays a set of square brackets around the key (DEFAULT) * @@ squiggly - Displays a set of squiggly brackets around the key * @@ parenthesis - Displays a set of parenthesis around the key * @@ FALSE - Turns off the display of bookends around the array key * * $key_padding STRING - The padding to use around the array key with printed * @@ quotes - Pads the array key with double quotes when printed * @@ apostrophe - Pads the array key with apostrophes when printed (DEFAULT) * @@ FALSE - Turns off the display of padding around the array key * * $number_of_tabs_to_use INT - The number of tabs to use when a sub array within the array creates a branch in the heirarchy * */ public function display_hierarchy($array, $key_bookends = '', $key_padding = '', $number_of_tabs_to_use = ''){ # Convert the input to a JSON and then back to an array just to make sure we know what we're working with $array = $this->convert_object_to_array($array); # If the $array variable is still not an array, then error out. # We're not going to fool around with your stupidity if(gettype($array) != 'array'){ echo 'Value submitted was '.strtoupper(gettype($array)).' instead of ARRAY or OBJECT. Only arrays or OBJECTS are allowed Terminating execution.'; exit(); } # Establish the bookend variables if($key_bookends != '' || !$key_bookends){ if(strtolower($key_bookends) == 'square'){ $this->display_square_brackets = TRUE; $this->display_squiggly_brackets = FALSE; $this->display_parenthesis = FALSE; }elseif(strtolower($key_bookends) == 'squiggly'){ $this->display_square_brackets = TRUE; $this->display_squiggly_brackets = TRUE; $this->display_parenthesis = FALSE; }elseif(strtolower($key_bookends) == 'parenthesis'){ $this->display_square_brackets = FALSE; $this->display_squiggly_brackets = FALSE; $this->display_parenthesis = TRUE; }elseif(!$key_bookends){ $this->display_square_brackets = FALSE; $this->display_squiggly_brackets = FALSE; $this->display_parenthesis = FALSE; } } # Establish the padding variables if($key_padding != '' || !$key_padding){ if(strtolower($key_padding) == 'apostrophe'){ $this->display_apostrophe = TRUE; $this->display_quotes = FALSE; }elseif(strtolower($key_padding) == 'quotes'){ $this->display_apostrophe = FALSE; $this->display_quotes = TRUE; }elseif(!$key_padding){ $this->display_apostrophe = FALSE; $this->display_quotes = FALSE; } } # Establish variable for the number of tabs if(isset($number_of_tabs_to_use) && $number_of_tabs_to_use != ''){ $this->number_of_tabs = $number_of_tabs_to_use; } foreach($array as $key => $value){ $this->insert_tabs(); if(is_array($value)){ echo $this->display_padding($key)." => {<BR>"; $this->counter++; $this->display_hierarchy($value); $this->counter--; $this->insert_tabs(); echo '} <BR>'; }else{ echo $this->display_padding($key)." => ".$value.'<BR>'; } } } # Inserts tab spaces for sub arrays when a sub array triggers a branch in the heirarchy # Helps to make the display more human readable and easier to understand private function insert_tabs(){ for($i=1; $i<=$this->counter; $i++){ for($x=1; $x<=$this->number_of_tabs; $x++){ echo '&emsp;'; } } } # Takes a PHP object and converts it to an array # Works with single dimension and multidimensional arrays public function convert_object_to_array($object){ $object = json_decode(json_encode($object), TRUE); return $object; } # Sets the displayed padding around the array keys when printed on the screen public function display_padding($value){ $default_container = "['VALUE_TO_REPLACE']"; $value = str_replace("VALUE_TO_REPLACE", $value, $default_container); if($this->display_square_brackets){ }elseif($this->display_squiggly_brackets){ $value = str_replace('[', '{', $value); $value = str_replace(']', '}', $value); }elseif($this->display_parenthesis){ $value = str_replace('[', '(', $value); $value = str_replace(']', ')', $value); }else{ $value = str_replace('[', '', $value); $value = str_replace(']', '', $value); } if($this->display_apostrophe){ }elseif($this->display_quotes){ $value = str_replace("'", '"', $value); }else{ $value = str_replace("'", '', $value); } return $value; } } ?> 
0
source

Source: https://habr.com/ru/post/1337812/


All Articles