我对php编码很陌生,自己也解决了很多问题,但有一个问题我无法理解。
$prep_stmt = "SELECT id FROM members WHERE Email = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
// check existing Email
if ($stmt) {
$stmt->bind_param('s', $Email);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// A user with this Email address already exists
$error_msg .= '<p class="error">A user with this Email address already exists.</p>';
$stmt->close();
}
$stmt->close();
} else {
$error_msg .= '<p class="error">Database error Line 39</p>';
$stmt->close();
}
我的猜测是,代码无法到达上面代码中的第二个$stmt->close();
(if中if后面的那个)。
我该如何解决这个问题?真的需要$stmt->close();
吗?
为什么不删除第一个(在第二个if语句中)?还要删除else
语句中的close()
,因为您检查了$stmt
是否为合法对象。基本上你说的是:$stmt
不是法律对象,关闭它。但关闭什么?
这在两种情况下都有效:
$prep_stmt = "SELECT id FROM members WHERE Email = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
// check existing Email
if ($stmt) {
$stmt->bind_param('s', $Email);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// A user with this Email address already exists
$error_msg .= '<p class="error">A user with this Email address already exists.</p>';
//Remove this one: $stmt->close();
}
$stmt->close();
} else {
$error_msg .= '<p class="error">Database error Line 39</p>';
//This one can be removed because $stmt isn't a legal object: $stmt->close();
}
只需删除if
语句和close()
方法调用。为什么要将其添加到代码中?
出现此错误的原因是,当语句创建失败时,您试图关闭它无法关闭从未创建过的对象。如果prepare()
调用失败,并且您的错误报告被静音,则此函数将返回false
而不是对象。
如果启用正确的错误报告,则不应存在if
语句。请参阅如何在MySQLi中获取错误消息?
以下是您的代码应该是什么样子的:
$prep_stmt = "SELECT id FROM members WHERE Email = ? LIMIT 1";
$stmt = $mysqli->prepare($prep_stmt);
// check existing Email
$stmt->bind_param('s', $Email);
$stmt->execute();
$result = $stmt->get_result();
if ($result->fetch_assoc()) {
// A user with this Email address already exists
$error_msg .= '<p class="error">A user with this Email address already exists.</p>';
}
尽量避开store_result()
。当您启用错误报告时,就没有理由使用任何if
语句。否则,您将需要在这样的语句中包装每一行,因为这些调用中的任何一个都可能失败:prepare()
、bind_param()
、execute()
。。。
如果获取了所有结果,就没有必要关闭该语句。当您调用get_result()
时,您可以从MySQL中获取所有内容。
保持简单,不要添加不必要的代码。
您应该将store_result()
放在执行之后,如下所示:
$stmt->execute();
$stmt->store_result();
如果您创建一个方法并传递查询,它将不起作用