Flat PHP Array to Hierarchy Tree
You should use recursion.
Here an exemple of code:
$datas = array( array('id' => 1, 'parent' => 0, 'name' => 'Page 1'), array('id' => 2, 'parent' => 1, 'name' => 'Page 1.1'), array('id' => 3, 'parent' => 2, 'name' => 'Page 1.1.1'), array('id' => 4, 'parent' => 3, 'name' => 'Page 1.1.1.1'), array('id' => 5, 'parent' => 3, 'name' => 'Page 1.1.1.2'), array('id' => 6, 'parent' => 1, 'name' => 'Page 1.2'), array('id' => 7, 'parent' => 6, 'name' => 'Page 1.2.1'), array('id' => 8, 'parent' => 0, 'name' => 'Page 2'), array('id' => 9, 'parent' => 0, 'name' => 'Page 3'), array('id' => 10, 'parent' => 9, 'name' => 'Page 3.1'), array('id' => 11, 'parent' => 9, 'name' => 'Page 3.2'), array('id' => 12, 'parent' => 11, 'name' => 'Page 3.2.1'), );function generatePageTree($datas, $parent = 0, $depth=0){ $ni=count($datas); if($ni === 0 || $depth > 1000) return ''; // Make sure not to have an endless recursion $tree = '<ul>'; for($i=0; $i < $ni; $i++){ if($datas[$i]['parent'] == $parent){ $tree .= '<li>'; $tree .= $datas[$i]['name']; $tree .= generatePageTree($datas, $datas[$i]['id'], $depth+1); $tree .= '</li>'; } } $tree .= '</ul>'; return $tree;}echo(generatePageTree($datas));
You can test it at: http://phpfiddle.org/main/code/1qy-5fj
Or if you want the exact format:
function generatePageTree($datas, $parent = 0, $depth = 0){ $ni=count($datas); if($ni === 0 || $depth > 1000) return ''; // Make sure not to have an endless recursion $tree = ''; for($i=0; $i < $ni; $i++){ if($datas[$i]['parent'] == $parent){ $tree .= str_repeat('-', $depth); $tree .= $datas[$i]['name'] . '<br/>'; $tree .= generatePageTree($datas, $datas[$i]['id'], $depth+1); } } return $tree;}
The test: http://phpfiddle.org/main/code/jw3-s1j
You can use FlatToTreeConverter class from Gears helper library:
<?phpnamespace Cosmologist\Gears\Collection;/** * Class able to convert a flat array with parent ID's to a nested tree */class FlatToTreeConverter{ /** * Convert a flat array with parent ID's to a nested tree * * @link http://blog.tekerson.com/2009/03/03/converting-a-flat-array-with-parent-ids-to-a-nested-tree/ * * @param array $array Flat array * @param string $idKeyName Key name for the element containing the item ID * @param string $parentIdKey Key name for the element containing the parent item ID * @param string $childNodesField Key name for the element for placement children * * @return array */ public static function convert(array $array, $idKeyName = 'id', $parentIdKey = 'parentId', $childNodesField = 'children') { $indexed = array(); // first pass - get the array indexed by the primary id foreach ($array as $row) { $indexed[$row[$idKeyName]] = $row; $indexed[$row[$idKeyName]][$childNodesField] = array(); } // second pass $root = array(); foreach ($indexed as $id => $row) { $indexed[$row[$parentIdKey]][$childNodesField][$id] = &$indexed[$id]; if (!$row[$parentIdKey]) { $root[$id] = &$indexed[$id]; } } return $root; }}
Not sure if you've found an answer yet, but I was looking for the same solution today and finally ended up making my own solution. The below code is the class I just created and it works with PHP arrays and objects and is recursive to an unlimited number of dimensions.
GitHub
https://github.com/DukeOfMarshall/PHP-Array-Heirarchy-Display
A simple example of using this code would be:
<?phprequire_once('Arrays.class.php');$display = new Array_Functions();$display->display_hierarchy($multidimensional_array);?>
There are other options that can be set as well, but that was just a straight up heirarchal display of an array or object.
<?phpclass Array_Functions {public $number_of_tabs = 3; # The default number of tabs to use when branching outprivate $counter = 0; # The counter to use for the number of tab iterations to use on the current branchpublic $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 understandprivate function insert_tabs(){ for($i=1; $i<=$this->counter; $i++){ for($x=1; $x<=$this->number_of_tabs; $x++){ echo ' '; } }}# Takes a PHP object and converts it to an array# Works with single dimension and multidimensional arrayspublic 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 screenpublic 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;}}?>