【问题标题】:Template system while in a while一会儿模板系统
【发布时间】:2013-02-20 21:43:16
【问题描述】:

我试图将 cmets 放在我循环的答案下方(就像 stackoverflow 上的答案一样)但我不知道如何将正确的评论放在正确的答案下方。我正在使用模板系统。 就我目前拥有的而言,它仅显示带有最后一个 $row['id']

的查询的 cmets

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>  

【问题讨论】:

    标签: php mysql mysqli template-engine


    【解决方案1】:

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

    首先,检索 cmets 的查询需要在您正在使用的两个表之间进行连接,否则它将执行两个表的笛卡尔积(每个答案都连接到每个评论,然后通过 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 个查询(甚至一个查询,但这是一个更微妙的问题,肯定会在它自己的讨论中产生)来解决这个问题。更好的方法是获取帖子的所有答案,然后获取与该帖子相关的所有 cmets。之后,您可以将 cmets 分组以了解每个 cmets 的来源。

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

    <?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 );
    

    【讨论】:

    • 非常感谢您抽出宝贵时间,但这没有用,对不起..以某种方式显示每个帖子的第一条评论。
    【解决方案2】:

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

    <?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);
    ?>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多