简体   繁体   English

如何使用父ID以嵌套方式显示注释

[英]How to display comments in a nested way with parent ID

I have a table comments , thats look like this, added some mockup content as well: 我有一个表comments ,就像这样,添加了一些模型内容:

+------------+---------+----------+-------------------+------------------------------------+---------------------------+
| comment_id | user_id | movie_id | comment_parent_id |          comment_content           | comment_creation_datetime |
+------------+---------+----------+-------------------+------------------------------------+---------------------------+
|         26 |       1 |    16329 |                 0 | Första                             | 2016-01-24 10:42:49       |
|         27 |       1 |    16329 |                26 | Svar till första                   | 2016-01-24 10:42:55       |
|         28 |       1 |    16329 |                26 | Andra svar till förta              | 2016-01-24 10:43:06       |
|         29 |       1 |    16329 |                28 | Svar till "andra svar till första" | 2016-01-24 10:43:23       |
+------------+---------+----------+-------------------+------------------------------------+---------------------------+

Im trying to display the comments Reddit style, like this image: 我试图显示评论Reddit样式,如下图:

在此输入图像描述

Im trying to fetch all comments SELECT * FROM comments WHERE movie_id = :movie_id ORDER BY comment_creation_datetime DESC and then recursively echo them out. 我试图获取所有注释SELECT * FROM comments WHERE movie_id = :movie_id ORDER BY comment_creation_datetime DESC然后递归回显它们。

I have tried a bunch of foreach loops, but none is working as expected 我尝试了一堆foreach循环,但没有一个按预期工作

foreach($this->comments as $value){ ?>
    <div class="comment">
        Comment content <?php echo $value->comment_content; ?>
            <?php if($value->comment_parent_id > 0){
    foreach($value as $sub_comment){ ?>
                <div class="comment">
                    comment comment on comment: <?php echo $value->comment_content; ?>
                </div>
            <?php }} ?>
    </div>
<?php }

My question: 我的问题:

How do I echo out the comments in a nested Reddit style with foreach loop? 如何使用foreach循环以嵌套的Reddit样式回显注释?

I would use some recursive function, you start with the ones with parent_id == 0 and recursively print all those who are their direct children. 我会使用一些递归函数,你从parent_id == 0开始,并递归打印所有直接孩子。

This code is not tested, but you can get the idea: 此代码未经过测试,但您可以获得以下建议:

function printComment($comment, $comments)
{
    foreach($comments as $c)
    {
        if($c->parent_id == $comment->comment_id)
        {
            $output .= "<li>".printCommment($c)."</li>";
        }
    }

    $output = "<ul>".$comment->comment_content."</ul>".$output;
    return $output;

}


foreach($this->comments as $comment)
{
    if($comment->parent_id == 0)
    {
        echo printComment($comment,$this->comments);
    }
}

Working with the adjacency list model can be more problematic with SQL. 使用邻接列表模型对SQL来说可能更成问题。 You need to retrieves all the rows with a single query and store a reference of any parent's child in a lookup table. 您需要使用单个查询检索所有行,并将任何父项的子项的引用存储在查找表中。

$sth = $pdo->prepare("SELECT * FROM comments WHERE movie_id = ? ORDER BY comment_creation_datetime DESC");
$sth->execute([$movie_id]);

$comments = $sth->fetchAll(PDO::FETCH_ASSOC);

$lookup_table = [];
foreach ($comments as $comment_key => $comment) {
    $lookup_table[$comment['comment_parent_id']][$comment_key] = $comment['comment_id'];
}

Now you can display them with 现在你可以用它们显示它们

function recursive_child_display($comments, $lookup_table, $root = 0, $deep = 0)
{
    if (isset($lookup_table[$root])) {
        foreach ($lookup_table[$root] as $comment_key => $comment_id) {
            // You can use $deep to test if you're in a comment of a comment

            echo '<div class="comment">';
            echo 'Comment content ', $comments[$comment_key]['comment_content'];
            recursive_child_display($comments, $lookup_table, $comment_id, $deep+1);
            echo '</div>';
        }
    }
}

Example: 例:

// display all the comments from the root
recursive_child_display($comments, $lookup_table, 0);

// display all comments that are parent of comment_id 26
recursive_child_display($comments, $lookup_table, 26);

You need to both make a list of root comments, and hierarchically organize all of them. 您需要创建根注释列表,并按层次结构组织所有注释。 You can do both in one go: 你可以一气呵成:

$roots = [];
$all = [];
foreach($comments as $comment)
{
  // Make sure all have a list of children
  $comment->comments = [];

  // Store all by ID in associative array
  $all[$comment->comment_id] = $comment;

  // Store the root comments in the roots array, and the others in their parent
  if(empty($comment->comment_parent_id))
    $roots[] = $comment;
  else
    $all[$comment->comment_parent_id]->comments[] = $comment;
}
// Check it's all done correctly!
print_r($roots);

You presorted the list by date, that's preserved in this approach. 您按日期对列表进行了预先排序,这是在此方法中保留的。 Also, as you only reorganized by reference this is lightning fast, and ready to be used in templating engines or anything - no need to print out inline like the other answers. 此外,由于您只是通过引用进行重新组织,因此它非常快速,可以用于模板引擎或其他任何东西 - 无需像其他答案一样打印出内联。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM