[英]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.