PHP 注册表单将数据写入数据库,即使 username/password 是 short/long 或密码不匹配。改变什么?

PHP registration form writes data to database even if username/password is short/long or passwords don't match. What to change?

我的 PHP 注册表需要帮助。我不知道出了什么问题。也许你可以看到它。即使提交的用户名或密码太短或太长以及密码不匹配,从我的注册表发送的数据也会写入数据库。 我的代码要更改什么?几个小时以来,我一直在努力纠正它。
提前致谢。

index.php 中的注册表包括 <?php session_start(); ?> 以上 HTML

<form class="sign-up" action="users.php" method="post">
    <p class="sign-up-title">Username:</p> <input class="sign-up-input" type="text" name="username" min="5" max="25">
    <p class="sign-up-title">Password:</p> <input class="sign-up-input" type="password" name="pass" min="6" max="35">
    <p class="sign-up-title">Confirm password:</p> <input class="sign-up-input" type="password" name="pass_check" min="6" max="35">
    <p class="sign-up-title">E-mail:</p> <input class="sign-up-input" type="email" name="email">
    <input id="sign-up-input-submit" class="sign-up-input" type="submit" value="Sign Up">
</form>
<?php
if (isset($_SESSION["username_error_short"])) {
    echo $_SESSION["username_error_short"];
}
elseif (isset($_SESSION["username_error_long"])) {
    echo $_SESSION["username_error_long"];
}
elseif (isset($_SESSION["username_error_exists"])) {
    echo $_SESSION["username_error_exists"];
}
elseif (isset($_SESSION["pass_error_short"])) {
    echo $_SESSION["pass_error_short"];
}
elseif (isset($_SESSION["pass_error_long"])) {
    echo $_SESSION["pass_error_long"];
}
elseif (isset($_SESSION["pass_error_mismatch"])) {
    echo $_SESSION["pass_error_mismatch"];
}
elseif (isset($_SESSION["email_error_exists"])) {
    echo $_SESSION["email_error_exists"];
}
elseif (isset($_SESSION["registration_success"])) {
    echo $_SESSION["registration_success"];
}
elseif (isset($_SESSION["registration_fail"])) {
    echo $_SESSION["registration_fail"];
}
?>


users.php

中的脚本
<?php

session_start();
include "connect.php";
global $db;

if (isset($_POST["username"]) || isset($_POST["pass"]) || isset($_POST["pass_check"]) 
    || isset($_POST["email"])) {

    $username = $_POST["username"];
    $password = $_POST["pass"];
    $password_check = $_POST["pass_check"];
    $email = $_POST["email"];

    // check if username is too short/long

    if (strlen($username) < 5) {

        $_SESSION["username_error_short"] = "Username too short. Username should contain at least 5 characters.";

    }
    elseif (strlen($username) > 25) {

        $_SESSION["username_error_long"] = "Username too long. Username should contain max. 25 characters.";

    }

    // check if username already exists in DB

    elseif (strlen($password) >= 5 || strlen($password) <= 25) {

        $sql_User_Duplicate = $db->prepare('SELECT * FROM users WHERE username = :username');
        $sql_User_Duplicate->bindParam(':username', $username);
        $sql_User_Duplicate->execute();

        if ($sql_User_Duplicate->rowCount() > 0) {

            $_SESSION["username_error_exists"] = "This username already exists. Select another one.";

        }
        else {

            $usernameCheck = 1;

        }

    }

    // check if password is too short/long

    if (strlen($password) < 6) {

        $_SESSION["pass_error_short"] = "Password too short. Password should contain at least 6 characters.";
        $passwordCheck_length = 0;

    }
    elseif (strlen($password) > 35) {

        $_SESSION["pass_error_long"] = "Password too long. Password should contain max. 35 characters.";
        $passwordCheck_length = 0;

    }

    // check if $password matches $password_check

    elseif (strlen($password) >= 6 || strlen($password) <= 35) {

        if ($password == $password_check) {

        $passwordCheck = 1;

        }
        else {

        $_SESSION["pass_error_mismatch"] = "Passwords don't match. Try again.";

        }

    }

    // check if email already exists in DB

    $sql_Email_Duplicate = $db->prepare('SELECT * FROM users WHERE email = :email');
    $sql_Email_Duplicate->bindParam(':email', $email);
    $sql_Email_Duplicate->execute();

    if ($sql_Email_Duplicate->rowCount() > 0) {

        $_SESSION["email_error_exists"] = "This e-mail is already registered.";

    }
    else {

        $emailCheck = 1;

    }

    // create new account

    if ($usernameCheck == 1 || $passwordCheck == 1 || $emailCheck == 1) {

        $sql_Account_Create = $db->prepare('INSERT INTO users (username, password, email) VALUES (:username, :password, :email)');
        $sql_Account_Create->execute(array(":username" => $username, ":password" => $password, ":email" => $email));

        // check if account (username) has been created in DB

        $sql_Account_Create_Check = $db->prepare('SELECT * FROM users WHERE username = :username');
        $sql_Account_Create_Check->bindParam(':username', $username);
        $sql_Account_Create_Check->execute();

        if ($sql_Account_Create_Check->rowCount() > 0) {

            $_SESSION["registration_success"] = "Account registered successfully.";

        }
        else {

            $_SESSION["registration_fail"] = "Something went wrong. Please check submitted data and try again later.";

        }

    }

}

header('Location: index.php');

?>

这些是我的建议:

  • 不要限制用户的密码。我只是检查以确保它不是空的。 查询 SELECT COUNT(*)SELECT * 并计算结果更快。
  • PDOStatement::execute returns true on success 所以你不必执行另一个查询来查看它是否正确插入
  • 文件末尾的尾随 ?> 是不必要的,在大多数情况下实际上是不鼓励的。
  • 将所有错误添加到一个数组中,这样您就不必在 index.php 文件中测试每种类型的数组。那样做不仅容易出错,而且非常乏味。您通常希望尝试使事情尽可能自动化,遍历事情而不是试图记住您之前使用过的所有测试条件。
  • 您想存储用户密码的哈希值,而不是明文密码。确保您的密码列类型足够长以存储 bcrypt 哈希值(参见:What column type/length should I use for storing a Bcrypt hashed password in a Database?)。
  • 确保您取消设置 $_SESSION['errors'],否则您的用户即使在成功填写表单后仍会继续向他们显示错误消息。

users.php:

<?php

session_start();
include "connect.php";
global $db;

if (isset($_POST["username"]) || isset($_POST["pass"]) || isset($_POST["pass_check"]) 
    || isset($_POST["email"])) {

    $username = $_POST["username"];
    $password = $_POST["pass"];
    $password_check = $_POST["pass_check"];
    $email = $_POST["email"];

    // check if username is too short/long

    if (strlen($username) < 5) {

        $_SESSION["errors"]["username"] = "Username too short. Username should contain at least 5 characters.";

    }
    elseif (strlen($username) > 25) {

        $_SESSION["errors"]["username"] = "Username too long. Username should contain max. 25 characters.";

    }

    // check if username already exists in DB

    elseif (strlen($username) >= 5 || strlen($username) <= 25) {

        $sql_User_Duplicate = $db->prepare('SELECT COUNT(*) FROM users WHERE username = :username');
        $sql_User_Duplicate->bindParam(':username', $username);
        $sql_User_Duplicate->execute();

        if ($sql_User_Duplicate->fetchColumn() > 0) {

            $_SESSION["errors"]["username"] = "This username already exists. Select another one.";

        }

    }

    // check if password is too short/long

    if (empty($password)) {

        $_SESSION["errors"]["password"] = "Your password is empty";

    }
    // check if $password matches $password_check

    elseif ($password != $password_check) {

        $_SESSION["errors"]["password"] = "Passwords don't match. Try again.";

    }

    // check if email already exists in DB

    $sql_Email_Duplicate = $db->prepare('SELECT COUNT(*) FROM users WHERE email = :email');
    $sql_Email_Duplicate->bindParam(':email', $email);
    $sql_Email_Duplicate->execute();

    if ($sql_Email_Duplicate->fetchColumn() > 0) {

        $_SESSION["errors"]["email"] = "This e-mail is already registered.";

    }

    // create new account

    if (!isset($_SESSION['errors']) {
        $hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);

        $sql_Account_Create = $db->prepare('INSERT INTO users (username, password, email) VALUES (:username, :password, :email)');
        $inserted = $sql_Account_Create->execute(array(":username" => $username, ":password" => $hash, ":email" => $email));

        if ($inserted !== true) {
            $_SESSION["errors"]["registration_fail"] = "Something went wrong. Please check submitted data and try again later.";
        }

    }

}

header('Location: index.php');

和index.php:

<form class="sign-up" action="users.php" method="post">
    <p class="sign-up-title">Username:</p> <input class="sign-up-input" type="text" name="username" min="5" max="25">
    <p class="sign-up-title">Password:</p> <input class="sign-up-input" type="password" name="pass" min="6" max="35">
    <p class="sign-up-title">Confirm password:</p> <input class="sign-up-input" type="password" name="pass_check" min="6" max="35">
    <p class="sign-up-title">E-mail:</p> <input class="sign-up-input" type="email" name="email">
    <input id="sign-up-input-submit" class="sign-up-input" type="submit" value="Sign Up">
</form>


<?php
if (isset($_SESSION["errors"])) {
    ?>
    There was a problem signing up:
    <ul>
    <?php
    foreach ($_SESSION['errors'] as $err) {
        echo "<li>$err</li>";
    }
    echo '</ul>';
    unset($_SESSION['errors']);
}
else {
    echo "Account registered successfully.";
}