PHP评论系统,1级回复。查询显示问题

时间:2012-06-18 08:43:58

标签: php mysql messaging

我正在尝试创建一个类似于facebooks墙的PHP评论系统,但每个帖子只有1个级别的回复。

我想要这种格式:

Post 1

Response 1
Response 2
Response 3

Add comment box

----------

Post 2
Response 1
Response 2
Response 3

Add comment box

但是,我的代码目前产生了这个结果:

Post 1
Response 1

Add comment box

Post 1
Response 2

Add comment box
----------------
Post 2
Response 1

Add comment box

---------------

Post 2
Response 1

Add comment box

---------------

我想遍历结果,以便每次循环时都不会将帖子消息与下一个与该帖子相关的注释一起打印出来。所以它应该遍历主消息一次,打印它,然后通过循环它们在下面发布所有相应的注释。

表格结构

帖子
  • p_id =该帖子的编号
  • user_id =他们发布的用户
  • poster_user_id =发帖的人
  • post
评论
  • comment_id =该评论的编号
  • post_id =评论与
  • 相关的帖子编号
  • commenter_user_id =发表评论的人
  • comment

代码

$query = "SELECT posts.p_id, comments.post_id, posts.poster_id,
      posts.user_id, message, `comments.commenter_user_id, comments.comment`
    FROM posts, comments
    WHERE posts.p_id = comments.post_id";
$query_run = mysql_query($query) or die(mysql_error());

while ($query_row = mysql_fetch_assoc($query_run)) {
    $pid = $query_row['p_id'];
    $post_id = $query_row['post_id'];
    $poster_id = $query_row['poster_id'];
    $user_id= $query_row['user_id'];
    $message = $query_row['message'];
    $commenter_user_id = $query_row['commenter_user_id'];
    $comment = $query_row['comment'];

    echo "
      <div id=\"post\">
        Post $pid $post_id Poster: $poster_id  Mentions: $user_id 
        <br><br> $message <br><br> 

        <ul class=\"comment\">
            $commenter_user_id 
            <li> $comment </li>
        </ul>

        <form name=\"message\" method=\"post\" action=\"sendmessage.php\">
        <textarea name=\"message\"></textarea> <br>
        <input type=\"submit\" value=\"Send\" /></form>
      </div>
      <br>";
}

关于如何产生预期结果的任何建议?我知道通过改变我的逻辑可能很容易解决这个问题,但我刚开始学习。非常感谢您对此的帮助!

更新

谢谢大家的帮助。我已经结合了代码示例的各个方面,它完美地运行。

还有一个问题:

如上所述,每个都包含注释。一旦评论发布,我希望用新帖子更新评论表。当我发表评论时,如何获取每个特定帖子的post_id和commenter_user_id变量,以便我可以使用该数据对评论表执行插入查询,如下所示:

INSERT INTO `comments`SET
    `post_id` = $post_id
    'commenter_user_id = $_SESSION['commenter_user_id'] " (I was thinking sessions?)

我想通过将变量通过url传递到脚本页来抓取数据:

    while ($query_row = mysql_fetch_assoc($query_run)){

// more variable definitions
$post_id = $query_row['post_id']



echo " <form method=\"post\" action=\"add_comment.php?post_id='.$post_id.'>
                <textarea name=\"comment\"></textarea> <br>
                <input type=\"submit\" value=\"Send\" /></form> "

但我尝试将变量传递给其他页面,如下所示:action = \“add_comment.php?post_id ='。$ post_id。' 但我得到一个未定义的索引:变量,当我尝试这样做。

有关如何实现这一目标的任何想法?

3 个答案:

答案 0 :(得分:4)

您的代码存在的问题是,对于您从数据库中读取的每条评论,您还可以从联接中获取帖子。我现在可以想到两种可能的解决方案:

第一个选项是保持您的查询不变,但无论何时打印一行,您都会看到您打印的帖子。您将存储最后打印的帖子ID,如果当前ID相同,您只是不打印帖子而只打印评论。这显然需要拆分帖子和评论的标记(无论如何这是一个好主意)。基本上这是这样的:

$lastPost = -1;
while ($query_row = mysql_fetch_assoc($query_run)) {
    // ...
    if ($pid != $lastPost) {
        echo "<code for the post>";
        $lastPost = $pid;
    }
    echo "<code for the comment>";
}

另一个想法是拆分您的查询,加载所有帖子,然后为您打印的每个帖子加载评论并打印所有。这显然需要对n+1帖子进行n SQL查询,但它会减少来自您的数据库的数据量(因为您不再为每个评论添加重复的帖子)。如果您有一个页面只显示一个帖子,那么这将允许您完全重用代码。它通常看起来像这样:

$query_run = // query only for posts, ignoring comments
while ($query_row = mysql_fetch_assoc($query_run)) {
    // ...
    echo "<code for the post>";

    $comment_query = // query only for comments with post_id = $pid
    while ($comment_row = mysql_fetch_assoc($comment_query)) {
        // ..
        echo "<code for the comment>";
    }
}

更新

您可以通过多种方式在表单中包含信息,然后将其传递到目标页面。一种方法是将它们作为GET参数包含在URL中,就像你自己尝试的那样。另一种方法是包含隐藏的输入元素,只保存静态数据。无论您使用什么,您都必须从目标页面上的$_GET$_POST获取这些值。在进行一些输入验证后(您应该这样做),您可以使用这些值来插入注释,就像通常只使用一个表单一样,除了post id也来自请求变量。如果您不知道如何正确处理用户输入并创建注释,我建议您开始慢一点,只需创建一个注释表单,以了解其工作原理。

“undefined index”错误意味着您尝试访问不存在的数组(可能是$query_row)中的索引。您只能访问在SQL查询中实际请求的那些值。因此,请检查您尝试访问的变量是否实际位于查询中。

答案 1 :(得分:1)

这就是我期望发生的事情,因为你的SQL查询是从两个表中选择内部连接 ​​- 所以你会得到行的重复。

直接在mysql查询窗口中尝试查询,看看会发生什么。

我建议存储当前帖子的值,并仅在帖子未更改时输出评论;如下所示:

此外,你没有在表单中记录帖子ID(作为隐藏变量或URL),所以我添加了一个隐藏变量,因为没有post_id,我怀疑这将是你的下一个bug。

    $last_post_id = null;

    while ($query_row = mysql_fetch_assoc($query_run)){

       $post_id = $query_row['post_id'];
       if ($last_post_id == $post_id)
       {
?>
                    <ul class=\"comment\">
                    $commenter_user_id 
                    <li> $comment </li>
                </ul>    
<?php
       }
       else
       {
          if ($last_post_id !== null)
          {
?>
                <form name=\"message\" method=\"post\" action=\"sendmessage.php\">
                <textarea name=\"message\"></textarea> <br>
                <input type=\"hidden\" name="\post_id\" value=\"$last_post_id\" />       </form>
                <input type=\"submit\" value=\"Send\" /></form>
<?php
              $last_post_id = $post_id;
          }
?>
           <div id=\"post\">
                Post $pid $post_id Poster: $poster_id  Mentions: $user_id 
                <br><br> $message <br><br> 
                <ul class=\"comment\">
                    $commenter_user_id 
                    <li> $comment </li>
                </ul>
            </div>
<?php
   }
?>

更新回答

<{1>}中的

(使用上面输入类型=隐藏的表单),请参见下文。您是正确的,您需要使用会话来获取当前用户ID以进行发布。

我建议使用POST方法提交任何导致数据修改的表单。

sendmessage.php

答案 2 :(得分:0)

递归怎么样?它适合您的需求吗?如果是,那么您需要的只是每条消息的父消息ID(如果它不是响应,则为NULL)。然后加载所有消息并仅使用NULL消息调用该函数,同时提供整个消息数组。