电子邮件已在数据库中,returns 好像不在

Email is already in database, returns as if it isn't

这里有一些关于我在这里要做的事情的背景信息。我正在尝试为我的网站创建一个注册表格(到目前为止是成功的)。数据可以输入到数据库中。我现在唯一要做的就是防止将重复的 email/usernames 输入到数据库中。通过对 Whosebug 的大量研究,我发现并测试了以下代码:

$query = "SELECT COUNT(*) AS num_rows FROM users WHERE email = ?";
$stmt = $mysqli->prepare($query);
$stmt->bind_param("s", $email);

if ($stmt->execute()) {
    return $stmt->num_rows;
}

我接下来要做的是:

if(user_exists($user_email) > 0) {
    echo "Email already exists!";
}

但是通过这个 if 语句就好像电子邮件确实存在于数据库中一样! 我尝试输入的电子邮件是 testemail@testemailweb.com,它已经在数据库中了!有人会指出我的代码哪里搞砸了吗?尝试执行此操作时我可能犯了一个愚蠢的错误吗?

变化:

if ($stmt->execute()) {
    return $stmt->num_rows;
}
What I then do is following:

if(user_exists($user_email) > 0) {
    echo "Email already exists!";
}

$j=0;
if ($stmt->execute()) {
    $j= $stmt->num_rows;
} else {
    echo "Email already exists!";
}

您的查询将总是 return 1 行。 COUNT(*) 将 return 一个结果集,即使只是报告没有匹配您的查询的行。结果 user_exists() 总是 returns 1.

将您的查询更改为:

$query = "SELECT * FROM users WHERE email = ?";

现在如果没有行匹配您的查询 $stmt->num_rows 将是 0 所以 user_exists() 将 return 0.

此处针对您的特定问题的解决方法是不使用 John 提到的 COUNT(*) 并且不依赖 mysqli_stmt->num_rows 通过使用缓冲结果集:

$query = "SELECT * FROM users WHERE email = ?";
$stmt = $mysqli->prepare($query);
$stmt->bind_param("s", $email);

return $stmt->execute() && $stmt->store_result() && $stmt->num_rows > 0;

附录

The only thing I'm trying to do now is prevent duplicate email/usernames from being entered into the db

您需要使用 table 约束来防止这种情况发生(不仅来自应用程序,还包括可以访问数据库的任何其他内容)。这具有防止竞争条件的额外好处。

ALTER TABLE users ADD UNIQUE(email);

如果您尝试插入具有已存在的电子邮件值的行,这将引发错误。您可以在应用程序端检查此错误,然后用它做任何您想做的事。