【问题标题】:PHP Comment System using Laravel使用 Laravel 的 PHP 评论系统
【发布时间】:2016-05-02 22:18:40
【问题描述】:

我正在使用 laravel PHP 开发一个网站,并尝试使用以下结构做一个评论系统:

- Comment 1 (id = 1)
 -- Reply 1 (id = 2) (parent_id = 1)
  --- Reply 2.1 (id = 3) (parent_id = 2)
 -- Reply 2 (id = 4) (parent_id = 1)

我想知道我将如何做一个 foreach 来覆盖它?因为我不知道一条评论会有多少个子 cmets。

【问题讨论】:

  • 将 cmets 和回复放在单独的表格中。在回复表链接中,使用comment->id 作为外键对评论的回复,称为comment_id
  • 是的。我就是这样做的。但我的意思是,我怎么知道每个评论需要多少个孩子来做 foreach。 @RiggsFolly
  • 您要么递归处理元素,要么向引用实际评论的回复添加另一个外键(总是) - 然后您可以基本选择指向评论的所有内容,然后根据父母

标签: php laravel for-loop


【解决方案1】:

不会将 cmets 和回复存储在单独的表中,因为它们在一天结束时都是评论实体。只需在 comments 表中添加一个 parent_id 列,您就可以在一个数据库查询中同时获取 cmets 和回复,而不是两个。

我假设您还有一个外键将评论链接到类似帖子的内容。然后,您可以获取该帖子 ID 的所有 cmets:

$comments = Comment::latest()->where('post_id', '=', $post->id)->get();

然后根据它们的parent_id 值对它们进行排序:

$comments = $comments->keyBy('parent_id');

然后您可以像这样在 Blade 模板中对它们进行迭代,每次迭代时,检查是否存在以该评论 ID 作为其父 ID 的 cmets:

<!-- Kick-start the loop -->
@foreach($comments[0] as $comment)
    @include('partials.comment')
@endforeach

partials/comment.blade.php

的内容
<blockquote class="comment">
    <p class="comment-body">{{ $comment->body }}</p>
    <footer>
        <span class="comment-author">{{ $comment->user->name }}</span>,
        <time class="comment-date" pubdate="pubdate">{{ $comment->created_at }}</time>
    </footer>
</blockquote>

@if(isset($comments[$comment['id']])
    @each('partials.comment', $comments[$comment['id'], 'comment')
@endif

【讨论】:

  • 我不知道出了什么问题,但它给了我:试图获取非对象的属性(查看:/var/www/html/blogando/resources/views/partials/comment.刀片.php)
  • @dante 因为您需要修改它以使用模型的实际属性,而不是复制粘贴我的答案。
  • 我的模型使用的名称与您使用的完全相同。在评论表 id、正文、on_post (post_id)、created_at、updated_at 上......
  • @dante $comment-&gt;user 怎么样?
  • 我没有使用.. 我只使用 $comment->body 来测试
【解决方案2】:
Table Like:

+------------+-----------+---------+
| comment_id | parent_id | comment |
+------------+-----------+---------+
|          1 |         0 | test    |
|          2 |         1 | test1   |
|          3 |         0 | test2   |
|          4 |         0 | test3   |
|          5 |         1 | test4   |
|          6 |         2 | test4   |
|          7 |         4 | test5   |
|          8 |         5 | test6   |
|          9 |         6 | test7   |
|         10 |         4 | test8   |
|         11 |         3 | test9   |
+------------+-----------+---------+


Get first level parent:

$comments = Comment::where('parent_id', '0')->orderBy('comment_id', 'asc')->get();

$result = array();
foreach($comments as $comment){
    $list = array();
    $list = array_merge($list, [['comment_id' => $comment->comment_id, 'parent_id' => $comment->parent_id, 'comment' => $comment->comment]]);
    $result = array_merge($result, $this->get_child_comment($comment->comment_id,0, $list));
}


function get_child_comment($pid,$level,$list=array()) {
        $sub_comments = Comment::where('parent_id','=',$pid)->where('comment_id','!=',$pid)->orderBy('comment_id', 'asc')->get();        
        foreach($sub_comments as $sub_comment){
            $space="&nbsp;"; sigm='-';
            for($j=0; $j<=$level; $j++)
            {
                $space .=$space;
            }
            for($j=0; $j<=$level; $j++)
            {
                $space .= $sigm;
            }
            $sub_comment->comment = html_entity_decode($space, ENT_QUOTES, "utf-8").' '.$sub_comment->comment;

            $list = array_merge($list, array(['comment_id' => $sub_comment->comment_id, 'parent_id' => $sub_comment->parent_id, 'comment' => $sub_comment->comment]));

            $list = $this->get_child_comment($sub_comment->comment_id, $level+1, $list);
        }
       return $list;
    }
}


return get array.simple print using foreach:
foreach($result as $val) {
    echo $val['comment'].'<br>';
}

Output:

test

  - test1

    -- test4

        --- test7

  - test4

    -- test6

test2

  - test9

test3

  - test5

  - test8

【讨论】:

  • 但是这里有一个疑问如何存储父ID
  • 父评论ID。
  • 是的,但我没有得到你在输出中显示的确切结果
  • 嗨,我可以问一下这个答案吗?我应该把function get_child_comment放在哪里?因为如果我把它放在我的public function ShowComment 里面,我会得到一个错误Method [get_child_comment] does not exist. 但是当我把它放在外面时,我没有得到任何错误,但它只是平坦的,没有空格/制表符来区分父母和孩子。谢谢
【解决方案3】:

您可以用以下结构表示 cmets:

$comments = [
    (object)[
        'id' => 1,
        'text' => 'Comment 1',
        'children' => [
            (object)[
                'id' => 2,
                'text' => 'Reply 1',
                'children' => [
                    (object)[
                        'id' => 2,
                        'text' => 'Reply 1.1'
                    ]
                ]
            ],
            (object)[
                'id' => 4,
                'text' => 'Reply 2',
            ]
        ]
    ]
];

并使用递归函数打印它们,如下所示:

function printComments($comments, $prefix = '-') {
    foreach ($comments as $comment) {
        echo $prefix.$comment->text.'<br>';
        isset($comment->children) && printComments($comment->children, $prefix.'-');
    }
}

或者在 Laravel 的情况下递归调用视图:

@include('cmets.view.path') 里面 @include('cmets.view.path')

为了方便地检索表示结构中的 cmets,并且通常用于使用树结构,我建议对具有 toHierarchy() 方法的 Laravel 使用 nested set modeletrepat/baum

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-29
    • 2011-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多