2011-04-07 214 views
1

我正在瀏覽關於使用數據庫執行菜單的視頻教程。我沒有像在視頻中那樣使用過程式PHP來做這件事,而是試着用準備好的語句OOP風格來做到這一點。它不起作用,我不明白爲什麼。PHP在準備好的語句中準備了語​​句

它運行良好,直到第17行,在那裏與此錯誤死亡:

Fatal error: Call to a member function bind_param() on a non-object in C:\wamp\www\widget_corp\content.php on line 17

而這裏的代碼:

<?php 
     $query = $connection->prepare('SELECT menu_name, id FROM subjects ORDER BY position ASC;'); 
     $query->execute(); 
     $query->bind_result($menu_name, $sid); 

     while ($query->fetch()){ 
      echo "<li>{$menu_name} {$sid}</li>"; 

      $query2 = $connection->prepare('SELECT menu_name FROM pages WHERE subject_id = ? ORDER BY position ASC;'); 
      $query2->bind_param("i", $sid); //This is line 17 
      $query2->execute(); 
      $query2->bind_result($menu_name); 
      echo "<ul class='pages'>";    
      while ($query2->fetch()){ 
       echo "<li>{$menu_name}</li>"; 
      } 
      echo "</ul>"; 

     } 
     $query->close(); 
    ?> 

是不可能內stmt-做一份準備好的聲明>取();?

+0

您使用的是mysqli擴展,對不對?你有沒有考慮過使用PDO?對於PDO,你可以將異常設置爲「錯誤處理程序」,這會讓你更難以錯過sql錯誤(就像這種情況下最可能由第16行導致的錯誤;-)) – VolkerK 2011-04-07 10:27:36

+0

是的,它是mysqli,但它不是sql錯誤。在終端中運行SQL查詢,工作正常。 – thekodols 2011-04-07 10:59:21

回答

8

想通了:

執行和結果結合後,它必須被存儲(如果另一個準備語句是在獲取被投入)。所以在這種情況下的讀取必須從緩衝結果中讀取。

換句話說,直到在同一連接上進行提取操作正在進行時,才能執行另一個查詢。

工作代碼:

$query = $connection->prepare("SELECT menu_name, id FROM subjects ORDER BY position ASC;"); 
$query->execute(); 
$query->bind_result($menu_name, $sid); 
$query->store_result(); 
+0

「...它必須被儲存「..救生員! – JohnA10 2015-08-26 22:31:26

0

是的,你可以有幾個準備好的陳述:準備陳述的想法之一是「準備一次,執行幾次」。

  • 所以,你應該準備語句的循環之外 - 所以它的準備只有一次
  • 並執行它,好幾次insidde循環。


你的致命錯誤意味着$query2第17行,是不是一個對象 - 這意味着失敗prepare

A prepare通常在發生錯誤時失敗;你確定你的查詢是有效的嗎?表格和列名稱都可以嗎?

你應該能夠得到一個錯誤信息,當prepare失敗,請使用mysqli->error() - 或PDO::errorInfo()

+0

如果我將它從循環中取出,查詢就可以正常工作。而「i」是整數,因此它知道把一個整數代替?。它不受名稱的約束。 – thekodols 2011-04-07 10:34:43

+0

Humph,對不起,我忘了這是如何工作:-(我已經刪除了我的答案的這部分...你是否嘗試得到由準備造成的錯誤信息? – 2011-04-07 10:37:23

+0

如果我把內部準備,並把它放在外面我只是沒有做任何事情,沒有任何錯誤,但沒有結果,也沒有得到任何其他的錯誤信息,除了原來的準備。(順便說一句,你有一些非常快速的反應時間,非常感謝你) – thekodols 2011-04-07 10:57:40

0

你不說你用的是什麼DB擴展,但你似乎並不測試返回您正在使用的任何功能的值。您不能認爲數據庫調用總是完美無缺。

2
$stmt = mysqli_prepare($con,"SELECT menu_name, id FROM subjects ORDER BY position ASC"); 
mysqli_stmt_execute($stmt); 
mysqli_stmt_bind_result($stmt, $menu_name, $id); 
while (mysqli_stmt_fetch($stmt)) 
{ 
$stmt2 = mysqli_prepare($con2,"SELECT menu_name FROM pages WHERE subject_id = ? ORDER BY position ASC;"); 
mysqli_stmt_bind_param($stmt2,$id); 
mysqli_stmt_execute($stmt2); 
mysqli_stmt_bind_result($stmt2, $name); 
while (mysqli_stmt_fetch($stmt2)) 
    echo $name; 
} 

看看$ CON和$ CON2,你不能執行使用相同的連接再使用ps內準備的語句!

+0

在這種情況下,不需要存儲結果,所以你節省了內存和時間:) – Sourav 2011-04-07 12:51:44