Php 如何使用1或2个查询构建线程化注释?

Php 如何使用1或2个查询构建线程化注释?,php,mysql,threaded-comments,Php,Mysql,Threaded Comments,有人能为一个线程评论系统推荐一个创造性的数据库结构+抓取算法吗?它可以在每页输出x个线程(每个线程的回复数量不限) 我可以运行一个查询来获取线程,并且在循环的每个实例中,运行另一个查询来回显回复。。。。但这是个坏主意 在注释表中添加两列:parentCommentId和rootCommentId parentCommentId是父注释的id,rootCommentId是启动此线程的注释的id 要显示N个线程,您需要两个查询: 从注释表中获取N行,其中rootCommentId=id 获取这N个线

有人能为一个线程评论系统推荐一个创造性的数据库结构+抓取算法吗?它可以在每页输出x个线程(每个线程的回复数量不限)


我可以运行一个查询来获取线程,并且在循环的每个实例中,运行另一个查询来回显回复。。。。但这是个坏主意

在注释表中添加两列:parentCommentId和rootCommentId

parentCommentId是父注释的id,rootCommentId是启动此线程的注释的id

要显示N个线程,您需要两个查询:

  • 从注释表中获取N行,其中rootCommentId=id
  • 获取这N个线程的所有注释

  • (您可以将这两个查询组合成一个GroupBy查询。)

    如果您只需要两个级别,这里有一个查询的方法:

    您的表-
    id、父id、注释

    代码

    $rows = mysql_query('
      select *
      FROM
        comments
      ORDER BY
        id DESC');
    
    $threads = array();
    foreach($rows as $row) {
      if($row['parent_id'] === '0') {
        $threads[$row['id']] = array(
          'comment' => $row['comment'],
          'replies' => array()
        );
      } else {
        $threads[$row['parent_id']]['replies'][] = $row['comment'];
      }
    }
    

    $threads
    中,您将拥有所有的主线程,
    $threads[$id]['replays']
    保存所有回复。线程已排序-latest=首先,添加一些分页,就可以开始了。

    这与我现在使用的类似。唯一棘手的部分是在有人回复评论时计算要插入的下一条回复路径

    示例数据

    ID | Comment                      | Path
    ---+------------------------------+----------
    0  | Comment #1                   | 01
    1  | Comment #1 reply             | 01_01
    2  | Comment #1 reply reply       | 01_01_01
    3  | Comment #1 reply reply       | 01_01_02
    4  | Comment #2                   | 02
    5  | Comment #3                   | 03
    6  | Comment #3 reply             | 03_01
    
    示例SQL

    SELECT * FROM comments ORDER BY path
    
    示例PHP

    while ($result = mysql_fetch_assoc($query)) {
        $nesting_depth = count(explode("_", $result['path']));
        $branch = str_repeat("--", $nesting_depth);
        echo $branch {$result['comment']}";
    }
    
    示例结果

    Comment #1
    -- Comment #1 reply
    ---- Comment #1 reply reply
    ---- Comment #1 reply reply
    Comment #2
    Comment #3
    -- Comment #3 reply
    
    回复01_01

    SELECT path FROM comments WHERE path LIKE '01\_01\___'
    
    $last_path = $row[0];
    $last_path_suffix = substr($last_path,strrpos($last_path,'_')+1);
    $next_path_suffix = str_pad($last_path_suffix+1,2,'0',STR_PAD_LEFT);
    $next_path = substr($last_path,0,strlen($last_path)-strlen($last_path_suffix)).$next_path_suffix;
    

    刚刚遇到这个问题并且必须解决它,我将在这里添加一个答案。一般的问题是带有回复的注释是一个树排序问题,而关系数据库并不适合这种情况。然而,评论数据库有一个非常有用的特性——它们是按顺序排列的,回复总是在它们作为答案的评论之后。这允许一个相当简单的编程解决方案;首先选择评论并将其保存到按id排序的数组中,然后通过数组添加字段“thread”和“threadbase”,其中threadbase是原始评论的id(例如0045),thread是回复的路径(例如0045/0050/0120)。php对于给定的id为的注释数组和回复字段为:

    uasort($comments, fnMakeComparer(['id', SORT_ASC]));
    
    $keys=array_keys($comments);
    
    //go through the comments adding thread and threadbase
    $n=count($comments);
    for($x=0;$x<$n;$x++){
    $key=$keys[$x];
    $replyto=$comments[$key]['reply_to'];
    $comments[$key]['thread']=$comments[$replyto]['thread']."/".$comments[$key]['id'];
    $comments[$key]['threadbase']=substr($comments[$key]['thread'],0,6);
    }
    
    //resort comments by threadbase (most recent first) then thread (oldest first)
    uasort($comments, fnMakeComparer((['threadbase', SORT_DESC]),['thread', SORT_ASC]),);
    
      
    
    uasort($comments,fnMakeComparer(['id',SORT_ASC]);
    $keys=数组_键($comments);
    //浏览添加线程和线程库的注释
    $n=计数($comments);
    
    对于($x=0;$x您如何将此查询限制为10篇帖子(包括他们的回复)?使用“限制10”,将只返回10行,不管他们是家长还是孩子。在这种情况下分页如何工作?另外,我知道我参加聚会迟到了。^ ^^@Bastien您知道如何分页或“加载更多评论”吗有这样的安排吗?