偶尔会有模板系统

时间:2013-02-20 21:43:16

标签: php mysql mysqli template-engine

我正在尝试将评论放在我循环的答案之下(就像stackoverflow上的答案一样)但我无法找到如何在正确答案下方放置正确的评论。我正在使用模板系统。 根据我目前的情况,它只显示最后$ row ['id']

的查询注释

PHP代码:

<?php
//Query setup for answers
$answerquery = "SELECT a.id, a.post_id, a.username, a.date, a.text FROM answers_tbl AS a, posts_tbl AS p WHERE a.post_id = p.id";
$result = $mysqli->query($answerquery);

//Replace answers
$layout_a = file_get_contents("tpl/question_answer_layout.html");
$search_a = array("%username%", "%date_a%", "%text_a%");
$answer_r = NULL;
while($row = $result->fetch_array()){
    $replace_a = array($row['username'], $row['date'], $row['text']);
    $answer_r .= str_replace($search_a, $replace_a, $layout_a);

    //Query setup for comments of the question
    $commentquery = "SELECT c.username, c.comment
                        FROM answer_comments_tbl AS c
                        INNER JOIN answers_tbl AS a ON a.id = c.answer_id
                        WHERE answer_id =".$row['id'];
    $result2 = $mysqli->query($commentquery);

    //Replace comments
    $layout_c = file_get_contents("tpl/question_comment_layout.html");
    $search_c = array("%comment_c%", "%username_c%");
    $answer_c = NULL;
    while($row2 = $result2->fetch_assoc()){
        $replace_c = array($row2['comment'], $row2['username']);
        $answer_c = str_replace($search_c, $replace_c, $layout_c);
        $answer_r = str_replace("%answer_comment%", $answer_c, $answer_r);
    }
}

$template = str_replace("%answer_post%", $answer_r, $template);
?>

question_answer_layout.html:

<div id="AnswerCarTop">


</div><!--Question-->

<div id="QuestionBottom">


<div id="QuestionTitle">%username%</div><!--QuestionTitle-->

<div id="Paragraph">%text_a%</div><!--Paragraph-->


%answer_comment%  

question_comment_layout.html:

<div id="CommentPlaced">
  <div id="Paragraph1">%comment% - <span class="bold">%username%</span></div>
<!--Paragraph--></div>  

2 个答案:

答案 0 :(得分:1)

您的代码存在一些问题,导致其无法正常运行。

首先,检索注释的查询需要在您正在使用的两个表之间进行连接,否则它将执行两个表的笛卡尔积(每个答案都连接到每个注释,然后通过where过滤)。你应该把它重写为:

SELECT c.username, c.comment
FROM answer_comments_tbl AS c
INNER JOIN answers_tbl AS a ON a.id = c.answer_id
WHERE answer_id = $row['id']

当然,使用准备好的陈述完全是另一回事。

第二个问题是您进行替换的顺序。基本结构(伪代码)应该是:

for each answer {
   for each comment {
       comment = apply the comment template
       comments_string += comment
   }
   apply the posts template, using the previously calculated comments_string
}

第三个问题是为每个答案执行单独查询的一般方法。你可以用2个查询(或者甚至是单个查询来解决这个问题,但这是一个更加微妙的问题,肯定会导致它自己的讨论)。更好的方法是获得帖子的所有答案,然后获得与该帖子相关的所有评论。之后,您可以对评论进行分组,以了解每个评论的来源。

这是完全编辑的代码。我没有添加预备语句,因为它超出了本答案的范围,但你绝对应该使用它们。

<?php
//Query setup for answers
$answerquery = "
    SELECT a.id, a.post_id, a.username, a.date, a.text
    FROM answers_tbl AS a
    INNER JOIN posts_tbl AS p ON a.post_id = p.id
    WHERE p.id = " . (int) $post_id;
$answerResult = $mysqli->query( $answerquery );

// Query setup for comments
$commentsQuery = "
    SELECT c.username, c.comment, c.answer_id
    FROM answer_comments_tbl AS c
    INNER JOIN answers_tbl AS a ON a.id = c.answer_id
    WHERE a.post_id = " . (int) $post_id;
$commentsResult = $mysqli->query( $commentsQuery );

// Group the comments by answer
$groupedComments = array();
while( $row = $mysqli->fetch_assoc( $commentsResult ) ) {
    if( ! isset( $groupedComments[ $row['answer_id'] ] ) ) {
        $groupedComments[ $row['answer_id'] ] = array();
    }
    $groupedComments[ $row['answer_id'] ][] = $row;
}

// Loading the template files only once
$layout_a = file_get_contents( 'tpl/question_answer_layout.html' );
$search_a = array( '%username%', '%date_a%', '%text_a%');

$layout_c = file_get_contents( 'tpl/question_comment_layout.html' );
$search_c = array( '%comment%', '%username%');

// This will hold the string with all the answers and their comments
$answers = null;
while( $row = $answerResult->fetch_assoc() ) {
    // This will hold all the comments for the current answer
    $answer_comment = null;
    foreach( $groupedComments[ $row['id'] ] as $comment ) {
        // Apply the comment layout
        $replace_c = array( $comment['comment'], $comment['username'] );
        $answer_comment .= str_replace( $search_c, $replace_c, $layout_c );
    }

    // Apply the answer layout
    $replace_a = array( $row['username'], $row['date'], $row['text'], $answer_comment );
    $answers .= str_replace( $search_a, $replace_a, $layout_a );
}

// Add all the answers and the comments to the main template
$template = str_replace( '%answer_post%', $answers, $template );

答案 1 :(得分:0)

这对我有用并解决了我的问题:

<?php
//Query setup for answers
$answerquery = "SELECT a.id, a.post_id, a.username, a.date, a.text FROM answers_tbl AS a, posts_tbl AS p WHERE a.post_id = p.id";
$result = $mysqli->query($answerquery);

//Replace answers
$layout_a = file_get_contents("tpl/question_answer_layout.html");
$search_a = array("%username%", "%date_a%", "%text_a%");
$answer_r = NULL;
while($row = $result->fetch_array()){
    $replace_a = array($row['username'], $row['date'], $row['text']);
    $answer_r .= str_replace($search_a, $replace_a, $layout_a);

    //Query setup for comments of the question
    $commentquery = "SELECT c.username, c.comment
                        FROM answer_comments_tbl AS c
                        INNER JOIN answers_tbl AS a ON a.id = c.answer_id
                        WHERE answer_id =".$row['id'];
    $result2 = $mysqli->query($commentquery);

    //Replace comments
    $layout_c = file_get_contents("tpl/question_comment_layout.html");
    $search_c = array("%comment%", "%username%");
    $answer_c = NULL;
    while($row2 = $result2->fetch_assoc()){
        $replace_c = array($row2['comment'], $row2['username']);
        $answer_c .= str_replace($search_c, $replace_c, $layout_c);
    }
        $answer_r = str_replace("%answer_comment%", $answer_c, $answer_r);
}

$template = str_replace("%answer_post%", $answer_r, $template);
?>