我知道有许多问题与我的问题类似。但我真的无法解决这里的问题。我的课程名为' UsersClass'负责与用户相关的每项任务。而且我使用mysqli prepare语句从数据库中插入或选择数据,问题是在很多情况下prepare语句返回false。我通过每次都建立新的连接解决了这个问题,但这导致了其他功能的另一个问题" 2006:Mysql服务器已经消失了#34;请参阅以下代码: 在这里和其他函数中,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;}
当我取消注释这两行时第一个函数将起作用并且准备staement不会返回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;
}}
那么如何解决第一个问题而不会出现新问题?
答案 0 :(得分:2)
...我使用mysqli prepare语句从数据库中插入或选择数据,问题是在很多情况下prepare语句返回false。
这是因为您以乱序方式运行查询,即您在关闭前一个语句对象之前执行->prepare()
。根据您当前的代码,在准备好的语句中添加以下错误报告代码,
if(!$this->_connection->prepare(...)){
printf('errno: %d, error: %s', $this->_connection->errno, $this->_connection->error);
die();
}
如果查看$this->_connection->error
,您会看到以下错误,
命令不同步;你现在不能运行这个命令
许多论坛都记录了这个问题,例如:
如果你的命令不同步;您现在无法在客户端代码中运行此命令,而是以错误的顺序调用客户端函数。
从此SO thread,
您不能同时拥有两个查询,因为默认情况下mysqli使用无缓冲的查询(对于预准备语句; ...
以正确的顺序执行命令,(See this example code)
(按照步骤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(...);