PHP Prepare方法在调用两次时不起作用


PHP Prepare method not working when calling it twice?

我使用的准备方法如下:

$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;
}

如果我执行脚本,我会得到

成功

有东西坏了:/

0

在第二次调用prepare方法后,我如何找出它失败的原因?由于某种原因,$db->errno返回0,这表示没有出现任何问题。但是,prepare方法失败并返回false,因此我无法检查$stmt->error;

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

编辑

根据Maxim Tkach的建议,如果我取消注释

// $stmt->close();

然后我得到

成功

成功

但为什么呢?我从来没有在任何地方读到过结束一个准备发言是至关重要的。

这来自PHP手册:

关闭准备好的语句。mysqli_stmt_close()还解除分配语句句柄。如果当前对账单有挂起或未读结果,此函数将取消它们,以便可以执行下一个查询已执行。

我看不出他们说为了执行第二份准备声明而结束是至关重要的。我是不是错过了什么?

您需要阅读以下内容:准备好的报表

prepared语句执行由两个阶段组成:prepared和处决在准备阶段,一个语句模板被发送到数据库服务器。服务器执行语法检查并初始化供以后使用的服务器内部资源。

每个准备好的语句都占用服务器资源。声明应使用后立即显式关闭。如果没有明确地进行,当语句句柄被释放时,该语句将被关闭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的检查返回值并执行-这将是好的

您需要读取$stmt->error;

要阅读,您需要按照下面的示例重写代码。

...
$stmt = new mysqli_stmt($db);
if($stmt->prepare('SELECT name FROM table WHERE id = ? '))
{
  $stmt->bind_param('i', $id);
  $stmt->execute();
  echo "Success<br>";
}
else {
  var_dump($stmt->error);
}
...