【问题标题】:How to build tree structure for comments?如何为评论建立树形结构?
【发布时间】:2016-03-14 09:47:05
【问题描述】:

我正在为博客文章获取所有 cmets,我还通过使用以下函数的引用将它们放在树结构中:

public function getComments($articleID) {
    $sql = "SELECT * FROM comments WHERE articleid = $articleID";
    $database = DatabaseFactory::getFactory()->Connect();
    $stmt = $database->query($sql);  
    $res = $stmt->fetchAll(PDO::FETCH_ASSOC);
    if($res!=NULL)
    {
        $references = array();
        $tree = array();
        foreach ($res as $id=> &$node) {
            // Use id as key to make a references to the tree and initialize it with node reference.
            $references[$node['comment_id']] = &$node;

            // Add empty array to hold the children/subcategories
            $node['children'] = array();

            // Get your root node and add this directly to the tree
            if ($node['comment_respond_to']==0) {
                $tree[$node['comment_id']] = &$node;
            } else {
                // Add the non-root node to its parent's references
                $references[$node['comment_respond_to']]['children'][$node['comment_id']] = &$node;
            }
        }

        return $tree;

当我print_r($tree);这是输出;

Array
(
    [1] => Array
        (
            [comment_id] => 1
            [articleid] => 1
            [user_id] => 2
            [comment_comment] => First comment.
            [comment_date] => 2016-03-10 20:06:43
            [comment_respond_to] => 0
            [children] => Array
                (
                    [2] => Array
                        (
                            [comment_id] => 2
                            [articleid] => 1
                            [user_id] => 1
                            [comment_comment] => First comment, first child.
                            [comment_date] => 2016-03-10 20:06:43
                            [comment_respond_to] => 1
                            [children] => Array
                                (
                                )
                    )

                [4] => Array
                    (
                        [comment_id] => 4
                        [articleid] => 1
                        [user_id] => 1
                        [comment_comment] => First comment, second child.
                        [comment_date] => 2016-03-10 20:06:43
                        [comment_respond_to] => 1
                        [children] => Array
                            (
                            )

                    )

            )

    )

[3] => Array
    (
        [comment_id] => 3
        [articleid] => 1
        [user_id] => 2
        [comment_comment] => Second comment.
        [comment_date] => 2016-03-10 20:06:43
        [comment_respond_to] => 0
        [children] => Array
            (
                [6] => Array
                    (
                        [comment_id] => 6
                        [articleid] => 1
                        [user_id] => 1
                        [comment_comment] => Second comment, first child.
                        [comment_date] => 2016-03-10 20:06:43
                        [comment_respond_to] => 3
                        [children] => Array
                            (
                            )

                    )

            )

    )

)       

一切都很完美。

是时候回声了。

我想要的输出:

  1. 第一条评论
    1. 第一个评论,第一个孩子。
    2. 第一个评论,第二个孩子。
  2. 第二条评论
    1. 第二条评论,第一个孩子。

所以,我知道我的下一步应该是使用 foreach 创建循环并获取 cmets。

我将return $tree; 替换为;

        foreach ($tree as $key) {
            echo '<li>'.$key["comment_comment"], '</li>';
        }

它输出;

  1. 第一条评论
  2. 第二条评论

儿童 cmets 丢失。 我知道我的下一步应该是在当前 foreach 中创建另一个 foreach 以获取子 cmets,但我不知道该怎么做。

感谢您的帮助。

【问题讨论】:

    标签: php


    【解决方案1】:

    一个简单的解决方案是使用recursion,例如

    <?php
    $comments = data();
    foo($comments);
    
    function foo($arr, $level=0) {
        $prepend = str_repeat(' ', $level); // <- the $level thingy is not necessary; it's only in here to get a bit prettier output
    
        echo $prepend, '<ul>', PHP_EOL;
        foreach($arr as $comment) {
            echo $prepend, '    <li>', $comment['comment_date'], ' ', htmlentities($comment['comment_comment']), PHP_EOL;
            if ( !empty($comment['children']) ) {
                foo($comment['children'], $level+1); // recurse into the next level
            }
            echo $prepend, '    </li>', PHP_EOL;
        }
        echo $prepend, '</ul>', PHP_EOL;
    }
    
    
    function data() {
        return array (
          1 => 
          array (
            'comment_id' => 1,
            'articleid' => 1,
            'user_id' => 2,
            'comment_comment' => 'First comment.',
            'comment_date' => '2016-03-10 20:06:43',
            'comment_respond_to' => 0,
            'children' => 
            array (
              2 => 
              array (
                'comment_id' => 2,
                'articleid' => 1,
                'user_id' => 1,
                'comment_comment' => 'First comment, first child.',
                'comment_date' => '2016-03-10 20:06:43',
                'comment_respond_to' => 1,
                'children' => 
                array (
                ),
              ),
              4 => 
              array (
                'comment_id' => 4,
                'articleid' => 1,
                'user_id' => 1,
                'comment_comment' => 'First comment, second child.',
                'comment_date' => '2016-03-10 20:06:43',
                'comment_respond_to' => 1,
                'children' => 
                array (
                14 => 
                      array (
                        'comment_id' => 14,
                        'articleid' => 1,
                        'user_id' => 99,
                        'comment_comment' => 'Comment to second child of First comment.',
                        'comment_date' => '2016-03-10 20:19:43',
                        'comment_respond_to' => 4,
                        'children' => 
                        array (
                        ),
                      ),
                ),
              ),
            ),
          ),
          3 => 
          array (
            'comment_id' => 3,
            'articleid' => 1,
            'user_id' => 2,
            'comment_comment' => 'Second comment.',
            'comment_date' => '2016-03-10 20:06:43',
            'comment_respond_to' => 0,
            'children' => 
            array (
              6 => 
              array (
                'comment_id' => 6,
                'articleid' => 1,
                'user_id' => 1,
                'comment_comment' => 'Second comment, first child.',
                'comment_date' => '2016-03-10 20:06:43',
                'comment_respond_to' => 3,
                'children' => 
                array (
                ),
              ),
            ),
          ),
        );
    }
    

    打印

    <ul>
        <li>2016-03-10 20:06:43 First comment.
        <ul>
            <li>2016-03-10 20:06:43 First comment, first child.
            </li>
            <li>2016-03-10 20:06:43 First comment, second child.
            <ul>
                <li>2016-03-10 20:19:43 Comment to second child of First comment.
                </li>
            </ul>
            </li>
        </ul>
        </li>
        <li>2016-03-10 20:06:43 Second comment.
        <ul>
            <li>2016-03-10 20:06:43 Second comment, first child.
            </li>
        </ul>
        </li>
    </ul>
    

    【讨论】:

      【解决方案2】:

      您应该在 foreach 中使用key =&gt; value 语法。 这样做:

          foreach ($tree as $key) {
          echo '<li>'.$key["comment_comment"], '</li>';
          if($key['children'])  {
              echo '<ul>';
              foreach($key['children'] as $child) {
                  echo '<li>'.$child["comment_comment"], '</li>';
              }
              echo '</ul>';
          }
      
      }
      

      //编辑: 如果有超过 1 个子级别,您应该使用递归循环。

      【讨论】:

      • 我很难理解为什么,但这段代码会调用每个列并列出它们。可以打印整数但不能自己注释。输出:i.imgur.com/HTfXdXt.png 第 156 行也是 echo '&lt;li&gt;'.$child["comment_comment"], '&lt;/li&gt;';
      猜你喜欢
      • 2013-08-30
      • 2014-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-25
      • 2021-08-20
      相关资源
      最近更新 更多