Php 查询mySQL以检查用户是否已经存在于两个表中

Php 查询mySQL以检查用户是否已经存在于两个表中,php,mysql,mysqli,registration,Php,Mysql,Mysqli,Registration,我正在学习如何为网站创建用户注册系统的教程。我已经做到了,但是我需要检查两个表中的多个值,看看它们是否存在。本教程没有这样做 这是我的登记表: <form action="/members/register/" name="registerForm"> <div> <h2>Register</h2> <h6>welcome</h6> <div class="reg

我正在学习如何为网站创建用户注册系统的教程。我已经做到了,但是我需要检查两个表中的多个值,看看它们是否存在。本教程没有这样做

这是我的登记表:

<form action="/members/register/" name="registerForm">
    <div>
        <h2>Register</h2>
        <h6>welcome</h6>
        <div class="register">
            <input type="text" name="firstname" placeholder="First Name" required>
            <input type="text" name="lastname" placeholder="Last Name" required>
            <input type="text" name="email" placeholder="Email" required>
            <label for="dob">Date of Birth:
                <input type="date" name="dob" id="dob" placeholder="Date of Birth" required>
            </label>
            <input type="text" name="username" placeholder="Username" required>
            <input type="password" name="password" placeholder="Password" required>
            <input type="password" name="passwordconfirm" placeholder="Confirm Password" required>
            <p>By creating an account you agree to our <a href="/legal/terms-of-use/">Terms &amp; Privacy</a>.</p>
            <button type="submit" name="registerNow">Register</button>
        </div>
    </div>
</form>
我需要创建一个查询,检查是否已经存在以下任何一项:1个名字和姓氏,2个用户名,或3封电子邮件

此外,一旦我了解了如何执行这样的查询,我仍然有点困惑,到底是什么?在查询中。此外,此代码示例仅检查用户名是否存在,以及输出的用户名是否已经存在。请选择另一个。我需要根据表中已存在的字段输出不同的内容。以下是教程中的代码:

if ($stmt = $con->prepare('SELECT id, password FROM accounts WHERE username = ?')) {
// Bind parameters (s = string, i = int, b = blob, etc), hash the password using the PHP password_hash function.
$stmt->bind_param('s', $_POST['username']);
$stmt->execute();
$stmt->store_result();
// Store the result so we can check if the account exists in the database.
if ($stmt->num_rows > 0) {
    // Username already exists
    echo 'Username already exists. Please choose another.';
} else {
    // Insert new account
}
$stmt->close();
} else {
// Something is wrong with the sql statement, check to make sure accounts table exists with all 3 fields.
echo 'Could not prepare statement!';
}
$con->close();
会是这样吗

SELECT id, password 
FROM users, registered 
WHERE users.username = ? OR (registered.nameFirst = ? AND registered.nameLast = ?) OR registered.email = ?

同样,我正在学习如何使用教程来实现这一点,所以我不想对代码的操作方式进行任何更改。我知道有更好的方法可以做到这一点。我将此作为学习和进步的起点。

因为您只需要检查注册值是否已经存在,所以使用EXISTS子查询可能比将两个表连接在一起更容易。大概是这样的:

SELECT
    EXISTS (SELECT * FROM users WHERE username = ?) AS found_username,
    EXISTS (SELECT * FROM registered WHERE nameFirst = ? AND nameLast = ?) AS found_name,
    EXISTS (SELECT * FROM registered WHERE email = ?) AS found_email
在这个查询中?表示用户名、名字、姓氏和电子邮件值的占位符。使用带有占位符的预处理语句的目的是防止SQL注入,有关这方面的更多信息,请参阅。使用它们还可以消除对输入中特殊字符转义的需要,例如,如果您想使用单引号中的值将O'Hara插入到nameLast字段中

因此,对于您的代码,您可以执行以下操作:

if ($stmt = $con->prepare('SELECT
        EXISTS (SELECT * FROM users WHERE username = ?) AS found_username,
        EXISTS (SELECT * FROM registered WHERE nameFirst = ? AND nameLast = ?) AS found_name,
        EXISTS (SELECT * FROM registered WHERE email = ?) AS found_email')) {
    // Bind parameters (s = string, i = int, b = blob, etc)
    $stmt->bind_param('ssss', $_POST['username'], $_POST['firstname'], $_POST['lastname'], $_POST['email']);
    $stmt->execute();
    $stmt->bind_result($found_username, $found_name, $found_email);
    $stmt->fetch();
    // Store the result so we can check if the account exists in the database.
    if ($found_username) {
        // Username already exists
        echo 'Username already exists. Please choose another.';
    }
    elseif ($found_name) {
        // Name already exists
        echo 'Name already exists. Please choose another.';
    }
    elseif ($found_email) {
        // Email already exists
        echo 'Email already exists. Please choose another.';
    }
    else {
        // Insert new account
    }
    $stmt->close();
} 
else {
    // Something is wrong with the sql statement, check to make sure accounts table exists with all 3 fields.
    echo 'Could not prepare statement!';
}
$con->close();

由于您只需要检查注册值是否已经存在,因此使用EXISTS子查询可能比将两个表连接在一起更容易。大概是这样的:

SELECT
    EXISTS (SELECT * FROM users WHERE username = ?) AS found_username,
    EXISTS (SELECT * FROM registered WHERE nameFirst = ? AND nameLast = ?) AS found_name,
    EXISTS (SELECT * FROM registered WHERE email = ?) AS found_email
在这个查询中?表示用户名、名字、姓氏和电子邮件值的占位符。使用带有占位符的预处理语句的目的是防止SQL注入,有关这方面的更多信息,请参阅。使用它们还可以消除对输入中特殊字符转义的需要,例如,如果您想使用单引号中的值将O'Hara插入到nameLast字段中

因此,对于您的代码,您可以执行以下操作:

if ($stmt = $con->prepare('SELECT
        EXISTS (SELECT * FROM users WHERE username = ?) AS found_username,
        EXISTS (SELECT * FROM registered WHERE nameFirst = ? AND nameLast = ?) AS found_name,
        EXISTS (SELECT * FROM registered WHERE email = ?) AS found_email')) {
    // Bind parameters (s = string, i = int, b = blob, etc)
    $stmt->bind_param('ssss', $_POST['username'], $_POST['firstname'], $_POST['lastname'], $_POST['email']);
    $stmt->execute();
    $stmt->bind_result($found_username, $found_name, $found_email);
    $stmt->fetch();
    // Store the result so we can check if the account exists in the database.
    if ($found_username) {
        // Username already exists
        echo 'Username already exists. Please choose another.';
    }
    elseif ($found_name) {
        // Name already exists
        echo 'Name already exists. Please choose another.';
    }
    elseif ($found_email) {
        // Email already exists
        echo 'Email already exists. Please choose another.';
    }
    else {
        // Insert new account
    }
    $stmt->close();
} 
else {
    // Something is wrong with the sql statement, check to make sure accounts table exists with all 3 fields.
    echo 'Could not prepare statement!';
}
$con->close();

我认为您希望SQL语句使用如下连接,以避免重复的行匹配:

选择 users.id,密码 从…起 用户注册加入 使用ID 哪里 用户名=? 或nameFirst=?和nameLast=? 或电子邮件=? 然后,需要将其他参数添加到绑定:

$stmt->bind_参数 “ssss”, $\u发布[用户名], $\u POST[名字], $\u POST[姓氏], $\邮政[电邮] ; $stmt->execute; //等等。
我认为您希望SQL语句使用如下连接,以避免重复的行匹配:

选择 users.id,密码 从…起 用户注册加入 使用ID 哪里 用户名=? 或nameFirst=?和nameLast=? 或电子邮件=? 然后,需要将其他参数添加到绑定:

$stmt->bind_参数 “ssss”, $\u发布[用户名], $\u POST[名字], $\u POST[姓氏], $\邮政[电邮] ; $stmt->execute; //等等。
无法保证users表和registered表中的id值具有相同的值集,在这种情况下,联接将省略registeredYou完全正确的部分行。我假设其中一个表是另一个表的外键,因为整个想法是注册唯一的用户。但就我而言,这很可能是一个错误的假设。感谢您指出这一点。这不是一个不合理的假设,良好的表设计会说用户和注册用户之间应该存在外键关系,但不清楚在这种特殊情况下是否存在外键关系。@Nick您完全正确。我最初认为,如果数据同时插入到两个表中,那么两个表的自动增量id都是相同的。意识到这不是真的,而且注册表中已经有了数据,我向users表添加了一个外键。感谢您指出这一点。不能保证users表和registered表中的id值具有相同的值集,在这种情况下,联接将忽略registeredYou中的一些行。我假设其中一个表是另一个表的外键,因为整个想法是注册唯一的用户。但就我而言,这很可能是一个错误的假设。感谢您指出这一点。这不是一个不合理的假设,好的表设计会说用户和注册用户之间应该有外键关系,但这并不清楚
在这种特殊情况下是存在的。@Nick你完全正确。我最初认为,如果数据同时插入到两个表中,那么两个表的自动增量id都是相同的。意识到这不是真的,而且注册表中已经有了数据,我向users表添加了一个外键。谢谢你指出这一点。首先不应该有两张桌子。您的所有字段必须在一个字段中table@YourCommonSense下面的答案证明了所有字段不必在一个表中,不是吗?我不明白你为什么说所有字段都必须在一个表中。如果有一个原因,他们应该在一个单一的表,而不是必须在一个单一的表,请让我知道。正如我在上面的问题中所说的,我对这一点还不熟悉,我正在学习,所以我非常感谢您的帮助。下面的答案证明不了什么,它们只是回答了您的问题。首先,没有理由在多个表之间拆分单个数据实体。你必须解释这种不自然的设计。如果您对此不熟悉,请在启动应用程序之前提出一个问题,即如何设计您的数据库。这篇文章针对自己的任务提出了一些观点,不管这些观点是否正确。这是关于多租户设计的,而您的案例并非如此。最好读一下KISS原理,只因为一个对你自己的系统有效的明确的技术理由而使你的系统复杂化,而不是因为有人为他们完全不同的系统做了什么。当你试图学习时,你必须让事情变得简单而不是复杂。你的设计已经让你提出了这个问题。您的代码已经比简单注册的代码复杂了十倍。大多数关系数据库设计在正确规范化时被认为是正确的,也有例外,但这就像一句老话,即在打破规则之前需要了解和理解规则。这里有一个关于各种形式的规范化以及如何实现它们的链接:首先不应该有两个表。您的所有字段必须在一个字段中table@YourCommonSense下面的答案证明了所有字段不必在一个表中,不是吗?我不明白你为什么说所有字段都必须在一个表中。如果有一个原因,他们应该在一个单一的表,而不是必须在一个单一的表,请让我知道。正如我在上面的问题中所说的,我对这一点还不熟悉,我正在学习,所以我非常感谢您的帮助。下面的答案证明不了什么,它们只是回答了您的问题。首先,没有理由在多个表之间拆分单个数据实体。你必须解释这种不自然的设计。如果您对此不熟悉,请在启动应用程序之前提出一个问题,即如何设计您的数据库。这篇文章针对自己的任务提出了一些观点,不管这些观点是否正确。这是关于多租户设计的,而您的案例并非如此。最好读一下KISS原理,只因为一个对你自己的系统有效的明确的技术理由而使你的系统复杂化,而不是因为有人为他们完全不同的系统做了什么。当你试图学习时,你必须让事情变得简单而不是复杂。你的设计已经让你提出了这个问题。您的代码已经比简单注册的代码复杂了十倍。大多数关系数据库设计在正确规范化时被认为是正确的,也有例外,但这就像一句老话,即在打破规则之前需要了解和理解规则。以下是有关各种形式的规范化以及如何实现规范化的链接: