[英]Prepared statement returning False
我知道有很多問題與我的問題相似。 但是我真的不明白這里的問題。 我有一個名為“ UsersClass”的類,它負責與用戶相關的每項任務。 而且我使用mysqli prepare語句從數據庫中插入或選擇數據,問題是在許多情況下prepare語句返回false。 我每時每刻都通過建立新連接來解決該問題,但這在其他功能中引起了另一個問題“ 2006:Mysql服務器已消失”,請參見下面的代碼:在此以及其他功能中,prepare返回false。
function isPostingAllowed() {
$this->setPsSelectUsers($this->_connection->prepare("Select * from userpermissions where userpermissions.UserId = ? and userpermissions.PermissionId = 1"));
$this->_psSelectUsers->bind_param('i',$this->UserId);
$this->_psSelectUsers->execute();
if ( false===$this->_psSelectUsers ) {
die('prepare() failed: ' . htmlspecialchars($this->_connection->error));}
if ($this->_psSelectUsers->fetch()){
return true;
}else{
return false;
}}
function setPsSelectUsers($stmt) {
$this->unsetPsSelectUsers();
// mysqli_close($this->_Connection);
// $this-> __construct();
$this->_psSelectUsers= $stmt;}
當我取消注釋這兩行時,第一個函數將起作用,並且准備工作不會返回false,但在這種情況下,以下函數將引發錯誤2006:
function checkUserAuthentication() {
$this->setPsSelectUsers($this->_connection->prepare("SELECT UserLogInName FROM Users WHERE UserLogInName=? AND UserPassword=?"));
$this->_psSelectUsers->bind_param('ss',$this->UserLogInName, $this->UserPassword);
$this->_psSelectUsers->execute();
if ($this->_psSelectUsers->fetch()){
return true;
}else{
return false;
}}
那么如何在不制造新問題的情況下解決第一個問題呢?
...我使用mysqli prepare語句從數據庫中插入或選擇數據,問題是在許多情況下prepare語句返回false。
這是因為您以亂序的方式運行查詢,即在關閉上一個語句對象之前正在執行->prepare()
。 給定您當前的代碼,在准備好的語句中添加以下錯誤報告代碼,
if(!$this->_connection->prepare(...)){
printf('errno: %d, error: %s', $this->_connection->errno, $this->_connection->error);
die();
}
如果您查看$this->_connection->error
,則會看到以下錯誤,
命令不同步; 您現在不能運行此命令
在許多論壇中都記錄了此問題,例如:
從MySQL文檔中 ,
如果命令不同步; 您現在無法在客戶端代碼中運行此命令,您以錯誤的順序調用了客戶端函數。
從這個SO線程 ,
您不能同時進行兩個查詢,因為mysqli默認情況下使用無緩沖查詢(對於准備好的語句; ...
以正確的順序執行命令( 請參閱此示例代碼 )
(盡管可以根據您的查詢選擇執行一個或多個步驟,但請按照步驟2至7執行所有查詢)
因此解決方案是,在再次調用->prepare()
之前,關閉上一個語句對象。 使用此方法調用$this->unsetPsSelectUsers();
出的setPsSelectUsers()
方法和之前把它if ($this->_psSelectUsers->fetch()){...}else{...}
塊isPostingAllowed()
和checkUserAuthentication()
方法。 此外,將$this->_psSelectUsers->fetch()
方法調用的狀態保存在變量中,並在隨后的if
塊中使用它。 因此,您的代碼應如下所示:
public function isPostingAllowed() {
$this->setPsSelectUsers($this->_connection->prepare("Select * from userpermissions where userpermissions.UserId = ? and userpermissions.PermissionId = 1"));
if(!$this->_psSelectUsers){
printf('errno: %d, error: %s', $this->_connection->errno, $this->_connection->error);
die();
}
$this->_psSelectUsers->bind_param('i',$this->UserId);
$this->_psSelectUsers->execute();
$status = $this->_psSelectUsers->fetch();
$this->unsetPsSelectUsers();
if ($status){
return true;
}else{
return false;
}
}
private function setPsSelectUsers($stmt){
$this->_psSelectUsers= $stmt;
}
private function unsetPsSelectUsers() {
if (isset($this->_psSelectUsers)) {
$this->_psSelectUsers->close();
unset($this->_psSelectUsers);
}
}
public function checkUserAuthentication() {
$this->setPsSelectUsers($this->_connection->prepare("SELECT UserLogInName FROM Users WHERE UserLogInName=? AND UserPassword=?"));
if(!$this->_psSelectUsers){
printf('errno: %d, error: %s', $this->_connection->errno, $this->_connection->error);
die();
}
$this->_psSelectUsers->bind_param('ss',$this->UserLogInName, $this->UserPassword);
$this->_psSelectUsers->execute();
$status = $this->_psSelectUsers->fetch();
$this->unsetPsSelectUsers();
if ($status){
return true;
}else{
return false;
}
}
此外,您不必再使用此setPsSelectUsers()
方法,可以在以下方法中直接使用屬性$_psSelectUsers
:
$this->_psSelectUsers = $this->_connection->prepare(...);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.