繁体   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