2011-12-05 48 views
0

我正在創建一個基於PHP的快速論壇,每個帖子在論壇中都會顯示在其「父」帖子下,但稍微縮進一些。PHP/MySQL嵌套提取?

要獲得該訂單的所有帖子,我有以下功能:

private function getData($pid, $offset) 
    { 
      $sql = 'SELECT id, subject, date 
        FROM post 
        WHERE forum_id = ? AND parent_id = ?'; 
      $sth = $this->db->prepare($sql); 
      $sth->bind_param("ii", $this->id, $pid); 
      $sth->bind_result($id, $subject, $date); 
      $sth->execute(); 

      $data = array(); 

      while ($sth->fetch()) 
      { 
        $row['id'] = $id; 
        $row['subject'] = $subject; 
        $row['date'] = $date; 
        $row['offset'] = $offset; 

        //Add this 'parent' post to the data array 
        $data[] = $row; 

        //Before moving on to next post, get all its children 
        $data[] = $this->getData($id, $offset+1); 
      } 

      $sth->close(); 

      return $data; 
    } 

,因爲我將結束,並從我目前的語句處理程序獲取的所有數據之前執行另一個查詢這是行不通的。

有沒有辦法可能分開查詢,使他們不相互衝突?或者任何其他方式繞過這個?或者我只需要重組我如何獲取數據?

+0

當你saythat這是行不通的,因爲你沒有開始一個新的前關閉一個查詢,你能更具體?你看到了什麼結果,或者什麼錯誤信息? –

+0

我有一個警告說:「所有數據必須在新的語句準備發生之前被提取」,這導致我的prepare()返回false並給我一個非對象錯誤。 – Benjamin

回答

2

將所有行提取到數組中,然後遍歷它們。

$rows = array(); 
while ($sth->fetch()) { 
    $row['id'] = $id; 
    $row['subject'] = $subject; 
    $row['date'] = $date; 
    $row['offset'] = $offset; 
    // the cool way is $rows[] = compact('id', 'subject', 'date', 'offset'); 
    $rows[] = $row; 
} 
$sth->close(); 

foreach ($rows as $row) { 
       //Add this 'parent' post to the data array 
       $data[] = $row; 

       //Before moving on to next post, get all its children 
       $data[] = $this->getData($id, $row['offset'] + 1); 
} 
1

我會給你一個例子來說明如何做到這一點,這是我將在例子中使用(後只需添加forum_id)表:

CREATE TABLE msgs (
    id INT NOT NULL AUTO_INCREMENT, 
    date DATETIME, 
    name VARCHAR(100), 
    message TEXT, 
    parent_id INT NOT NULL DEFAULT 0 
); 

然後,使用一個查詢更多信息:

$query = mysql_query("SELECT * FROM msgs ORDER BY id"); 

某些陣列打造 「的帖子樹」,所有PARENT_ID = 0將是根的帖子:

$all_messages = array(); // Will store all messages 
$root_messages = array(); // Will store only the root (or more than one if you allow) 

while($row=mysql_fetch_assoc($query)){ // Main loop 
     $all_messages[$row['id']] = array(
       'inner_messages'=>array(), 
       'date'=> $row['date'], 
       'name'=> $row['name'], 
       'message'=>$row['message'], 
       'id'=>$row['id'] 
       ); 
     if($row['parent_id']=='0'){ // If is a root post 
     $root_messages[] = &$all_messages[$row['id']]; 
     }else{ // If not a root post, places within parent message 
     $all_messages[$row['parent_id']]['inner_messages'][] = &$all_messages[$row['id']]; 
     } 
} 

現在打印,使用遞歸:

function writeTree($msgs){ 
    foreach($msgs as $m){ 
     echo '<div>'; 
     echo '<h2>'.$m['name'].' ('.$m['date'].')</h2>'; 
     echo '<div class="text">'.$m['message'].'</div>'; 
     writeTree($m['inner_messages']); 
     echo '</div>'; 
    } 
} 
writeTree($root_messages);