PHP Prepare方法在调用两次时无法正常工作?

我使用的准备方法如下:

$db= new MysqLi("localhost","***","***","***");

if ($db->connect_error) {
  die('Connection Error');
}

$id = 1;
if($stmt = $db->prepare('SELECT name FROM table WHERE id = ? '))
{
  $stmt->bind_param('i', $id);
  $stmt->execute();
  // $stmt->close();
  echo "Success<br>";
}
else {
  echo "Something broke :/<br>";
}

$id =2;
if($stmt = $db->prepare('SELECT name FROM table WHERE id = ? '))
{
  $stmt->bind_param('i', $id);
  $stmt->execute();
  echo "Success<br>";
}
else {
  echo "Something broke :/<br>";
  $error = $db->errno . ' ' . $db->error;
  echo $error;
}

如果我执行脚本,我得到

Success

Something broke :/

0

在第二次调用后,如何找出准备方法失败的原因?出于某种原因,$db-> errno返回0,表示没有出错.但是,prepare方法失败并返回false,所以我无法检查$stmt->错误;

我偶然发现当我删除一个$stmt-> execute()调用时,再次调用prepare方法工作正常(在第一次和第二次调用时).我在这里错过了什么?

编辑

正如Maxim Tkach所建议的,如果我取消注释

// $stmt->close();

然后我明白了

Success

Success

但那是为什么呢?我从来没有读过关闭准备声明至关重要的地方.

这来自PHP手册:

Closes a prepared statement. MysqLi_stmt_close() also deallocates the
statement handle. If the current statement has pending or unread
results, this function cancels them so that the next query can be
executed.

我没有看到他们说为了执行第二份准备声明而关闭至关重要.我错过了什么吗?

解决方法:

你需要阅读:Prepared Statements

The prepared statement execution consists of two stages: prepare and
execute. At the prepare stage a statement template is sent to the
database server. The server performs a Syntax check and initializes
server internal resources for later use.

Every prepared statement occupies server resources. Statements should
be closed explicitly immediately after use. If not done explicitly,
the statement will be closed when the statement handle is freed by
PHP.

在阅读完文章后,我总结道:
如果不关闭一个查询,则无法准备查询.执行后,请务必准备好结束查询.

您的代码应该重写如下:

$db= new MysqLi("localhost","***","***","***");
if ($db->connect_error) {   
      die('Connection Error'); 
}
$id = 1; 
if($stmt = $db->prepare('SELECT name FROM table WHERE id = ? ')) { 
      $stmt->bind_param('i', $id);   
      $stmt->execute(); 
      echo "Success<br>"; 
} else {   
       echo "Something broke :/<br>"; 
}

$id = 2;
$stmt->bind_param('i', $id); 
$stmt->execute();
$stmt->close();   

P.S如果你添加bind和execute的检查返回值 – 这将是好的

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...