Flat PHP Array to Hierarchy Tree

后端 未结 3 1464
天涯浪人
天涯浪人 2020-12-03 02:11

I have an array with the following keys

id   
parent_id
name

A sample array:

array(7) {
  [0]=>
  array(3) {
    [\"id\"         


        
相关标签:
3条回答
  • 2020-12-03 02:20

    You can use FlatToTreeConverter class from Gears helper library:

    <?php
    namespace 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;
        }
    }
    
    0 讨论(0)
  • 2020-12-03 02:28

    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

    0 讨论(0)
  • 2020-12-03 02:43

    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:

    <?php
    
    require_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.

    <?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 讨论(0)
提交回复
热议问题