簡體   English   中英

准備好的語句返回False

[英]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默認情況下使用無緩沖查詢(對於准備好的語句; ...

解:

以正確的順序執行命令( 請參閱此示例代碼

  1. 打開連接(一次:從一開始,而不是在每個查詢執行期間)
  2. 創建准備好的語句
  3. 綁定參數
  4. 執行查詢
  5. 綁定結果變量
  6. 將值提取到那些綁定變量中
  7. 關閉語句對象
  8. 關閉連接(一次:在最后,而不是在每個查詢執行期間)

(盡管可以根據您的查詢選擇執行一個或多個步驟,但請按照步驟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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM