2012-01-04 127 views
0

我在腳本room.php中運行了兩個查詢。兩者都是使用的MySQLi準備語句,而且他們的代碼如下:MySQLi無法準備語句

/* Get room name */ 
$stmt = $mysqli->prepare('SELECT name FROM `rooms` WHERE r_id=?'); 
$stmt->bind_param('i', $roomID); 
$stmt->execute(); 
$stmt->bind_result($roomName) 

/* Add this user to the room */ 
$stmt = $mysqli->prepare('INSERT INTO `room_users` (r_id, u_id) VALUES (?, ?)'); 
$stmt->bind_param('ii', $roomID, $_SESSION['userID']); 
$stmt->execute(); 

當我運行該腳本,我得到這個錯誤:

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

這是第二次查詢。如果我從腳本中刪除第一個查詢,那麼一切運行良好。同樣,如果我刪除第二個查詢。這導致我認爲存在問題,因爲我正在重新使用$stmt對象。如果我使用$stmt2嘗試第二個查詢,我仍然會收到錯誤消息。

我所有的數據庫表和字段都存在,所以查詢沒有問題。

回答

7

所有的mysqli函數/方法可能會失敗,在這種情況下它們將返回false。即如果prepare()失敗$ stmt不是一個對象,你可以調用一個方法,但是一個bool(false)。你必須檢查返回值並添加一些錯誤處理,例如

$stmt = $mysqli->prepare('SELECT name FROM `rooms` WHERE r_id=?'); 
if (!$stmt) { 
    printf('errno: %d, error: %s', $mysqli->errno, $mysqli->error); 
    die; 
} 

$b = $stmt->bind_param('i', $roomID); 
if (!$b) { 
    printf('errno: %d, error: %s', $stmt->errno, $stmt->error); 
} 

$b = $stmt->execute(); 
if (!$b) { 
    and so on and on 

看到http://docs.php.net/mysqli-stmt.errno


在這種情況下

你可能碰到了,你不能創建的其它陳述的問題,同時還存在着結果/上一個聲明未決結果集。
看到http://docs.php.net/mysqli-stmt.close

Closes a prepared statement. mysqli_stmt_close() also deallocates the statement handle. If the current statement has pending or unread results, this function cancels them so that the next query can be executed.
+0

@Bill:你是絕對正確的,不知道爲什麼你的編輯請求已被拒絕.... – VolkerK 2013-12-12 13:31:17

+2

第二部分是對我來說關鍵。 '$ mysqli-> prepare'返回false,但是'$ mysqli-> error'爲空;在前面的語句中加入'$ stmt-> close'就可以解決這個問題。 – Clamburger 2013-12-19 05:43:21