人们注册时如何防止重复的用户名?

Posted

技术标签:

【中文标题】人们注册时如何防止重复的用户名?【英文标题】:How to prevent duplicate usernames when people register? 【发布时间】:2021-09-24 08:28:14 【问题描述】:

我一直在制作登录/注册系统,并且即将完成我的注册部分代码。我遇到的唯一问题是如何使用户无法使用重复的用户名注册。我希望它能够工作,这样我的数据库就不会接受这些信息,它会告诉用户这个错误。

我的 php

<?php

include 'database_connection.php';
if (isset($_POST['formsubmitted'])) 
    $error = array(); //Declare An Array to store any error message
if (empty($_POST['name'])) //if no name has been supplied
    $error[] = 'Please Enter a name '; //add to array "error"
 else 
    $name = $_POST['name']; //else assign it a variable


    if (empty($_POST['e-mail'])) 
        $error[] = 'Please Enter your Email ';
     else 
        if (preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/", $_POST['e-mail'])) 
            //regular expression for email validation
            $Email = $_POST['e-mail'];
         else 
            $error[] = 'Your EMail Address is invalid  ';
        
    

    if (empty($_POST['Password'])) 
        $error[] = 'Please Enter Your Password ';
     else 
        $Password = $_POST['Password'];
    

    if (empty($error)) 
        //send to Database if there's no error '
    

【问题讨论】:

不要使用自定义正则表达式来验证电子邮件地址,有效的电子邮件地址允许在本地部分使用 + 号。使用 filter_input(INPUT_POST, FILTER_VALIDATE_EMAIL, .... 【参考方案1】:

防止数据库中重复用户名的最佳方法是使数据库列 PRIMARY KEY 或将其标记为 UNIQUE。

-- Make it a primary key
ALTER TABLE users ADD PRIMARY KEY(username);
-- or set it to be unique
ALTER TABLE users ADD UNIQUE (username);

这将防止表中具有相同用户名的重复记录。当您尝试插入相同的内容时,将产生错误。

然后您可以在 PHP 中捕获异常并检查原因。重复约束SQL错误码为1062。

以下是使用 PDO 时如何捕获此错误的示例:

$error = [];
$username = 'Dharman';

$pdo = new \PDO("mysql:host=localhost;dbname=test;charset=utf8mb4", 'user', 'password', [
    \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,  // make sure the error reporting is enabled!
    \PDO::ATTR_EMULATE_PREPARES => false
]);

try 
    $stmt = $pdo->prepare('INSERT INTO users(username) VALUE(?)');
    $stmt->execute([$username]);
 catch (\PDOException $e) 
    if ($e->errorInfo[1] === 1062) 
        $error[] = "This username is already taken!";
    

以下是使用 mysqli 时如何捕获此错误的示例:

$error = [];
$username = 'Dharman';

// make sure the error reporting is enabled!
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'user', 'password', 'test');
$mysqli->set_charset('utf8mb4');

try 
    $stmt = $mysqli->prepare('INSERT INTO users(username) VALUE(?)');
    $stmt->bind_param('s', $username);
    $stmt->execute();
 catch (\mysqli_sql_exception $e) 
    if ($e->getCode() === 1062) 
        $error[] = "This username is already taken!";
    

【讨论】:

我认为最好在没有该字段 id 主键的情况下对字段“用户名”设置唯一约束?但是我同意你的唯一约束解决方案。 是否有办法计算出什么是重复列,因为使用电子邮件地址也很常见。有时这些必须是唯一的以及用户名。 @NigelRen 是的,异常消息包含列的名称。您可以使用正则表达式来获取它,但这超出了此答案的范围。 列名的提取正如你所说的另一个问题,只是想明确一点,如果定义了多个唯一列,这仍然可以工作(它不必是唯一的唯一列)。【参考方案2】:

我使用了一个PDO和类方法,可能会有一些用处。

//function for checking if the user already exists in the database
public function userExists($username)


    //prepared statements for added security
    $query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `username`= ?");
    $query->bindValue(1, $username);

    try 
        //execute the query
        $query->execute();
        $rows = $query->fetchColumn();

        //if a row is returned...user already exists
        if ($rows == 1) 
            return true;
         else 
            return false;
        
        //catch the exception
     catch (PDOException $e) 
        die($e->getMessage());
    

也要注意准备好的语句——绝对是前进的方向

【讨论】:

【参考方案3】:

例如,当用户发布用户名并单击提交时,您可以这样做,您可以编写此代码或将其添加到您的代码中:

<?php

$connect = mysql_connect('whatever', 'whatever', 'whatever');
$database = mysql_select_db('your dbname');
$username = $_POST['username'];
if (isset($username)) 
    $mysql_get_users = mysql_query("SELECT * FROM table_name where username='$username'");

    $get_rows = mysql_affected_rows($connect);

    if ($get_rows >= 1) 
        echo "user exists";
        die();
     else 
        echo "user do not exists";
    

【讨论】:

非常感谢您对我的 +rep,我很高兴这个答案对您有用,我只是想对您说些什么,当您创建用户列时,您可以做到唯一的,例如创建表用户(用户名 varchar(350) 不是 null 唯一的),祝你好运:) 请不要使用给定的代码。它对 SQL 注入广泛开放 不仅对SQL注入开放,当两个或多个用户同时使用相同的用户名注册时,代码不起作用。最好的解决方案是使用 UNIQUE 索引,或者将此代码包装在事务中。【参考方案4】:

你应该做两件事。

    使用户名成为数据库表中的主键。这很容易使用 phpmyadmin 完成。

    在插入之前验证。

对于第二步,这里有一个算法。您可以使用 pdo、mysqli 甚至 mysql 以自己的方式实现它(虽然现在不推荐)。

代码末尾的算法(即,如果没有错误)...

选择与帖子中提供的 USERNAME 匹配的记录。

如果存在,给出错误。

如果不存在,插入它。

【讨论】:

以上是关于人们注册时如何防止重复的用户名?的主要内容,如果未能解决你的问题,请参考以下文章

防止用户在注册firebase后自动登录[重复]

生成注册激活密钥时如何防止冲突?

如何防止用户在文本框中输入特殊字符[重复]

如何防止在asp.net中注册用户重定向

php 在自己本身的页面如何防止重复提交的

Session 防止表单重复提交