Php 如何防止用户注册时出现重复用户名?

Php 如何防止用户注册时出现重复用户名?,php,mysql,duplicates,Php,Mysql,Duplicates,我一直在做一个登录/注册系统,我即将完成我的注册部分的代码。我遇到的唯一问题是如何使用户不能使用重复的用户名注册。我希望它能正常工作,这样我的数据库就不会接受这些信息,它会告诉用户错误 我的PHP <?php include 'database_connection.php'; if (isset($_POST['formsubmitted'])) { $error = array(); //Declare An Array to store any error message

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

我的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 '
    }
}

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

<?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";
    }
}

有两件事你应该做

  • 使用户名成为数据库表中的主键。使用phpmyadmin很容易做到这一点

  • 插入前进行验证

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

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

    选择与文章中提供的用户名匹配的记录

    如果存在,请给出一个错误

    如果它不存在,请插入它


    我用了一个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());
        }
    }
    

    还要注意准备好的语句-明确地说,前进的方向是防止数据库中出现重复用户名的最佳方法是使数据库列成为主键或将其标记为唯一的。

    ——将其设为主键
    ALTER TABLE users添加主键(用户名);
    --或者将其设置为唯一的
    ALTER TABLE users添加唯一(用户名);
    
    这将防止表中具有相同用户名的重复记录。当您尝试插入同一个时,将生成一个错误

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

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

    $error=[];
    $username='Dharman';
    $pdo=new\pdo(“mysql:host=localhost;dbname=test;charset=utf8mb4”,“user”,“password”[
    \PDO::ATTR_ERRMODE=>\PDO::ERRMODE_异常,//确保已启用错误报告!
    \PDO::ATTR_EMULATE_PREPARES=>false
    ]);
    试一试{
    $stmt=$pdo->prepare('插入用户(用户名)值(?);
    $stmt->execute([$username]);
    }捕获(\p异常$e){
    如果($e->errorInfo[1]==1062){
    $error[]=“此用户名已被使用!”;
    }
    }
    
    以下是使用mysqli时如何捕获此错误的示例:

    $error=[];
    $username='Dharman';
    //确保已启用错误报告!
    mysqli_报告(mysqli_报告错误| mysqli_报告严格);
    $mysqli=newmysqli('localhost','user','password','test');
    $mysqli->set_字符集('utf8mb4');
    试一试{
    $stmt=$mysqli->prepare('插入用户(用户名)值(?));
    $stmt->bind_参数($s',$username);
    $stmt->execute();
    }捕获(\mysqli\u sql\u异常$e){
    如果($e->getCode()==1062){
    $error[]=“此用户名已被使用!”;
    }
    }
    
    非常感谢您为我提供+rep,我很高兴这个答案对您有效。我想告诉您,当您创建用户列时,您可以使其唯一,例如创建表用户(username varchar(350)not null unique),祝您好运:)请不要使用给定的代码。它对SQL注入非常开放不仅对SQL注入开放,而且当两个或多个用户同时使用同一用户名注册时,代码不起作用。最好的解决方案是使用唯一索引,或者将此代码包装到事务中。我认为最好在没有字段id主键的字段“username”上设置唯一约束?不过,我同意你对“唯一约束”的解决方案。是否有办法确定什么是重复列,因为使用电子邮件地址也很常见。有时,这些名称和用户名必须是唯一的。@NigelRen是的,异常消息包含列的名称。您可以使用正则表达式来获取它,但这超出了此答案的范围。列名的提取是您所说的另一个问题,只是想说明,如果定义了多个唯一列,这仍然有效(它不必是唯一唯一的列)。不要使用自定义正则表达式来验证电子邮件地址,有效的电子邮件地址允许在本地部分使用+号。使用过滤输入(输入发布、过滤验证电子邮件等)。。。。