-1

ループする回答の下にコメントを入れようとしています(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>  
4

2 に答える 2

1

コードには、正しく動作するのを妨げるいくつかの問題があります。

まず、コメントを取得するクエリは、使用している 2 つのテーブル間で結合を行う必要があります。そうしないと、2 つのテーブルのデカルト積が実行されます (すべての回答がすべてのコメントに結合され、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']

もちろん、準備済みステートメントを使用することは、まったく別の問題です。

2 番目の問題は、置換を行う順序です。基本構造 (疑似コード) は次のようになります。

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

3 番目の問題は、すべての回答に対して個別のクエリを実行するという一般的なアプローチです。この問題は、たった 2 つのクエリで解決できます (または 1 つのクエリでも解決できますが、それはよりデリケートな問題であり、それ自体の議論につながることは間違いありません)。より良いアプローチは、投稿に対するすべての回答を取得してから、その投稿に関連するすべてのコメントを取得することです。その後、コメントをグループ化して、それぞれのコメントがどこから来たのかを知ることができます。

これが完全に編集されたコードです。この回答の範囲を超えているため、準備済みステートメントは追加しませんでしたが、必ず使用する必要があります。

<?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 );
于 2013-02-20T22:13:38.337 に答える
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);
?>
于 2013-02-20T23:25:34.663 に答える