簡體   English   中英

如何使用父ID以嵌套方式顯示注釋

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

我有一個表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       |
+------------+---------+----------+-------------------+------------------------------------+---------------------------+

我試圖顯示評論Reddit樣式,如下圖:

在此輸入圖像描述

我試圖獲取所有注釋SELECT * FROM comments WHERE movie_id = :movie_id ORDER BY comment_creation_datetime DESC然后遞歸回顯它們。

我嘗試了一堆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 }

我的問題:

如何使用foreach循環以嵌套的Reddit樣式回顯注釋?

我會使用一些遞歸函數,你從parent_id == 0開始,並遞歸打印所有直接孩子。

此代碼未經過測試,但您可以獲得以下建議:

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);
    }
}

使用鄰接列表模型對SQL來說可能更成問題。 您需要使用單個查詢檢索所有行,並將任何父項的子項的引用存儲在查找表中。

$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'];
}

現在你可以用它們顯示它們

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>';
        }
    }
}

例:

// 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);

您需要創建根注釋列表,並按層次結構組織所有注釋。 你可以一氣呵成:

$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);

您按日期對列表進行了預先排序,這是在此方法中保留的。 此外,由於您只是通過引用進行重新組織,因此它非常快速,可以用於模板引擎或其他任何東西 - 無需像其他答案一樣打印出內聯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM