我有一个评论系统。每条评论都可能收到回复,每个回复都会收到回复,但令人作呕。
因此,我的数据库包含一个名为“comments”的表,其中包含以下重要字段:
id
text
reply_to
...在reply_to下,当然是评论的回复。
所以现在,问题很简单:如何显示所有评论,但知道每条评论后必须回复它,并且每次回复后必须回复回复等等?
我最努力的东西,以及我一直在回归的东西,是这样的:
$query = mysql_query("SELECT * FROM comments WHERE reply_to=0");
while ($comment = mysql_fetch_array($query))
include("comment.php");
在comment.php中,我所拥有的是:
foreach ($comment as $key = $value) $$key = $value;
echo $text;
echo "<div style='margin-left:30px;'>"; //A margin for a little indent
$subquery = mysql_query("SELECT * FROM comments WHERE reply_to=$id");
while ($comment = mysql_fetch_array($subquery))
include("comment.php");
echo "</div>";
但是,如果我正确地再现了我的代码的本质,问题是:在第一个回复被回应后,它继续第一个回复的第一个回复,然后是第一个回复的第一个回复第一个回复,但循环永远不会到达任何东西的第二个回复。例如,假设表有3条评论,每条评论有3条回复,每条评论都有3条回复等,上面的代码会输出:
Comment
First reply
First second-order reply
First third-order reply
...
我希望我已经清楚地解释了它。 inb4:我无法在表中添加新列。
答案 0 :(得分:2)
在伪代码中:
function display_comment(comm)
echo comm's info and text
children = get children of the comment: SELECT from comments WHERE parent = (comm's id)
echo <div class="comment-thread">
foreach children as child
display_comment(comm) // notice this line
echo </div>
你必须创建一个函数,以递归引用它。
答案 1 :(得分:0)
我通常这样做
function get_comments($text_id, $parent_id,$depth){
$sql="SELECT * FROM spam WHERE parent_id='".(int)$parent_id."' AND text_id='".(int)$text_id."' ";
//..query
while ($row=mysql_fetch_assoc($query)){
//some comment output use $depth*pixels to indent
$depth++;
get_comments($text_id,$row['parent_id'],$depth);
$depth--;
}
}
并在第一次通话中
get_comments($text_id,0,0); //
答案 2 :(得分:0)
$subquery = mysql_query(SELECT * FROM comments WHERE reply_to=$comment_id);
可能有些错误。当您描述表格定义时,带有comment`s id的字段名为id
,但您在此处使用的是comment_id
。此外,您没有将SQL语句括在引号(' '
)中。是复制粘贴相关的错误吗?
答案 3 :(得分:0)
首先是DB:
+--------------------------+
| comments |
+--------------------------+
| id (INT) | <-- a unique id for the comment
| post_id (INT) | <-- the original post / article being replied to
| parent_id (INT) | <-- the comment this is in response to
| commenter_email (VARCHAR)| <-- just some way to identify the commenter
| comment_text (TEXT) | <-- the actual comment
+--------------------------+
第二个伪代码:
function print_comment($comment_id, $replies_children, $comments)
{
// For every comment at this level...
foreach($reply_id in $replies_children[$comment_id])
{
// Create a div container to contain both this comment AND
// all child comments. We let CSS take care of indenting.
echo '<div style="padding-left: 10px;">';
// Print this comment first...
echo $comments[$reply_id]['comment_text'];
// And beneath it print all of the replies to this comment
print_comment($reply_id, $replies_children, $comments);
// Finally end this level of comment indentation
echo '</div>';
}
}
// Fetch all of the comments at once for post id 10
$sql = "SELECT * FROM comments WHERE post_id = 10;";
// Get the results back (associative array, please)
$results = execute_sql($sql);
// Holds a list of replies (comment ids) for each comment
$replies_children = array();
// Lets us map an ID to the actual full sql result
$comments = array();
foreach($result in $results)
{
// Make sure there's a list for the parent
if($replies_children doesnt have key $result['parent_id']))
$replies_children[$results['parent_id']] = array();
// Append this item to the parent's list
$replies_children[$result['parent_id']][] = $result['id'];
// Allows us to get to this result by id directly
$comments[$result['id']] = $result;
}
// Assume that id = 0 is the root level
print_comment(0, $replies_children, $comments);
这样你只需要调用一次数据库。
答案 4 :(得分:0)
如果你还包括深度列,你的生活会更容易。