2011-08-11 18 views
1

시스템에 의견이 있습니다. 각 의견은 답장을받을 수 있으며 각 답장은 답장을받을 수 있습니다. while 중첩 된 루프

는 따라서, 내 데이터베이스는 다음과 같은 중요한 분야로 "의견"라는 이름의 테이블이 포함

id 
text 
reply_to 

... REPLY_TO에서, 물론, 주석의 ID를 간다가 응답되는.

이제 문제는 간단합니다. 모든 의견을 표시하는 방법은 무엇입니까?하지만 각 의견이 답장을받은 후 각 답장이 답장을 보내야합니다.

$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>"; 

그러나 경우

내가 가장 노력 무엇을하고, 무엇을 내가 다시오고 계속하면이 같은 것입니다 나는 내 코드의 본질을 올바르게 재현했다. 문제는 이것이다 : 첫 번째 응답이 에코 된 후 첫 번째 응답의 첫 번째 응답으로 이어지고 첫 번째 응답의 첫 번째 응답의 첫 번째 응답은 계속되지만 루프는 결코 두 번째 응답에 도달하지 않습니다. 나는 그것을 충분히 명확하게 설명했다 희망

Comment 
    First reply 
    First second-order reply 
     First third-order reply 
     ... 

: 그래서 예를 들면, 테이블을 상정하는 것은 위의 코드 출력 것, 3 개의 대답했다 각각 3 개의 댓글을했고, 그 각각은 등 3 개 응답을했다. inb4 : 테이블에 새 열을 추가 할 수 없습니다. 의사에서

+4

당신은 함수에 코드를 포장하고, 그 재귀를 확인해야합니다. http://stackoverflow.com/questions/2648968/what-is-a-recursive-function-in-php – mario

+1

다른 일이라면 잠에서 깨어 난 후 몇 시간 동안 코드에 대해 생각하지 마십시오. 당신이 하루 종일 당신의 머리를 두들겨 봤다면 ** 잠시 떨어져 나간다. ** –

+1

루프에서 데이터베이스를 치는 것도 좋은 생각이 아니다. id는 1 개의 쿼리에서 모든 관련 주석을 얻은 다음 루프/재귀를 사용하여 표시합니다. –

답변

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> 

, 그것은 반복적으로 참조 할 수 있습니다.

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); // 
+0

루프에서 준비된 SQL 문을 실행하지 않기로하는 것은 대단히 좋지 않습니다. – Timur

+0

나는 이것을 단지 재귀 루핑의 예제로 게시했으나 sql의 예제는 게시하지 않았다. 나는 그가 db에 저장된 id 옆에 그것을 정리하기 전에 정수가되어야하고 이미 정리되어야한다고 생각했다. 하지만 내 게시물을 변경했습니다 –

+1

SQL 문은 이미 루프에 있습니다 :) 준비된 문 - http://dev.mysql.com/doc/refman/5.5/en/sql-syntax-prepared-statements.html, http : // php .net/manual/ko/mysqli.prepare.php – Timur

0
$subquery = mysql_query(SELECT * FROM comments WHERE reply_to=$comment_id); 

몇 가지 실수가 될 수 있습니다. 테이블 정의를 설명 할 때 comment`s id가있는 필드의 이름은 id이지만 여기서는 comment_id을 사용하고 있습니다. 또한 SQL 문을 따옴표로 묶지 않습니다 (' '). 복사 - 붙여 넣기 관련 실수입니까?

+0

예, 죄송합니다. 지금 바로 ... – Sophivorus

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

이 방법 .