skip to Main Content

I have a task where I must to get hierarchy tree from given array. An arrays inside array looks:

$commentsArray = [
    [1, 1, 'Comment 1'],
    [2, 1, 'Comment 2'],
    [3, 2, 'Comment 3'],
    [4, 1, 'Comment 4'],
    [5, 2, 'Comment 5'],
    [6, 3, 'Comment 6'],
    [7, 7, 'Comment 7'],
];

now I need to get output into html like:

Comment 1
-- Comment 2
----Comment 3 
------Comment 6
----Comment 5
--Comment 4
Comment 7  

My code doesn’t work:

<?php

$commentsArray = array(
    array(
        'id' => 1,
        'parent_id' => 1,
        'content' => 'Comment 1'
    ),
    array(
        'id' => 2,
        'parent_id' => 1,
        'content' => 'Comment 2'
    ),
    array(
        'id' => 3,
        'parent_id' => 2,
        'content' => 'Comment 3'
    ),
   ...
);

$new = array();

foreach ($commentsArray as $comment){
    $new[$comment['parent_id']][] = $comment;
}

$tree = createTree($new, array($commentsArray[0]));

echo '<pre>';
print_r($tree);
echo '</pre>';

function createTree(&$list, $parent){
    
    $tree = array();
    
    foreach ($parent as $k=>$l){
        
        if(isset($list[$l['id']])){
            $l['children'] = createTree($list, $list[$l['id']]);
        }
        
        $tree[] = $l;
    } 
    
    return $tree;
}

I tried to run script without first element of $commentsArray and it works but I need the first element

3

Answers


  1. Chosen as BEST ANSWER

    I did it myself. But Thanks anyway!

    <?php
    
    class CommentService
    {
    /**
     * @param array $commentsArray
     *
     * @return string
     */
    public function getHierarchyTreeDOM(array $commentsArray): string
    {
        $processedIds = [];
    
        $htmlDOM = '<ul>';
    
        foreach ($commentsArray as $comment) {
    
            if ($comment[0] === $comment[1]) {
                $htmlDOM .= '<li>' . $comment[2];
                $htmlDOM .= $this->buildHierarchyRecursively($commentsArray, $comment[0], $processedIds);
                $htmlDOM .= '</li>';
            }
    
        }
    
        return $htmlDOM . '</ul>';
    }
    
    /**
     * @param array $commentsArray
     * @param int $parentId
     * @param array $processedIds
     *
     * @return string
     */
    private function buildHierarchyRecursively(array $commentsArray, int $parentId = 1, array &$processedIds = []): string
    {
        $htmlDOM = '<ul>';
    
        foreach ($commentsArray as $item) {
    
            if ($item[0] !== $parentId && $item[1] === $parentId && !in_array($item[0], $processedIds)) {
                $processedIds[] = $item[0];
    
                $htmlDOM .= '<li>' . $item[2];
                $htmlDOM .= $this->buildHierarchyRecursively($commentsArray, $item[0], $processedIds);
                $htmlDOM .= '</li>';
            }
    
        }
    
        return $htmlDOM . '</ul>';
    }
    
    }
    

    Then in html page:

    <?php
    
    require_once('CommentService.php');
    
    $commentService = new CommentService();
    
    $commentsArray = [
        [1, 1, 'Comment 1'],
        [2, 1, 'Comment 2'],
        [3, 2, 'Comment 3'],
        [4, 1, 'Comment 4'],
        [5, 2, 'Comment 5'],
        [6, 3, 'Comment 6'],
        [7, 7, 'Comment 7'],
    ];
    
    ?>
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, 
    maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Comments</title>
    </head>
    <body>
        <h2>Comments:</h2>
        <?php
    
            echo $commentService->getHierarchyTreeDOM($commentsArray);
    
        ?>
    </body>
    </html>
    

  2. <?php
    
    $comments = [
        [1, 1, 'Comment 1'],
        [2, 1, 'Comment 2'],
        [3, 2, 'Comment 3'],
        [4, 1, 'Comment 4'],
        [5, 2, 'Comment 5'],
        [6, 3, 'Comment 6'],
        [7, 7, 'Comment 7'],
    ];
    
    $map = [];
    
    foreach($comments as $c) {
        $id = $c[0] === $c[1] ? 0 : $c[1];
        $map[$id][] = $c;
    }
    
    function print_comments($arr, $depth) {
        global $map;
        foreach($arr as $c) {
            echo str_repeat("--", $depth) . "{$c[2]}n";
            print_comments($map[$c[0]] ?? [], $depth+1);
        }
    }
    
    print_comments($map[0], 0);
    
    Login or Signup to reply.
  3. You could use two functions:

    • One to iteratively create the hierarchy structure.
    • One to recursively create HTML for that hierarchy.
    function createForest(&$list) {
        $bykey = [0 => ["children" => []]];
        foreach ($list as [$id, $parentid, $comment]) {
            $bykey[$id] = ["comment" => $comment, "children" => []];
            $bykey[$parentid == $id ? 0 : $parentid]["children"][] = &$bykey[$id];
        }
        return $bykey[0]["children"];
    }
    
    function createHtml(&$forest) {
        $html = "";
        foreach ($forest as ["comment" => $comment, "children" => $children]) {
            $html .= "<li>$comment" . createHtml($children) . "</li>";
        }
        return $html ? "<ul>$html</ul>" : "";
    }
    
    $commentsArray = [
        [1, 1, 'Comment 1'],
        [2, 1, 'Comment 2'],
        [3, 2, 'Comment 3'],
        [4, 1, 'Comment 4'],
        [5, 2, 'Comment 5'],
        [6, 3, 'Comment 6'],
        [7, 7, 'Comment 7'],
    ];
    $forest = createForest($commentsArray);
    $html = createHtml($forest);
    echo $html;
    

    Output:

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search