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.";
}
我的 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.";
}