我使用的准备方法如下:
$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的检查返回值 – 这将是好的