PDO MySQL 不区分大小写的查询区分大小写 AND SQLSTATE[23000]:违反完整性约束:1062 键重复条目 'user_name'

PDO MySQL case insensitive query is case sensitive AND SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry for key 'user_name'

当某人(本周早些时候)能够使用相同的电子邮件地址(区分大小写)注册两个帐户时,我第一次注意到这个问题。我已经通过在注册时添加 strtolower 来解决这个问题,并且暂时添加了 LOWER 进行查询(我想我应该制作所有以前存在的电子邮件数据库中的小写字母,因此我不需要在查询中使用 LOWER。

我现在遇到麻烦的部分(我已经花了大约 5 天的时间来弄明白了)是弄清楚如何查询不区分大小写 现有的用户名在数据库中并在注册期间与新用户名进行比较(同样不区分大小写)。

它不起作用(我认为查询默认情况下不区分大小写,但它似乎不是?)因为我不断收到此 SQLSTATE[23000]:违反完整性约束:1062 重复entry '[name entered in registration for here]' for key 'user_name'

这部分看起来,至少对我来说,很简单,它是独一无二的,所以我不能在数据库中有两个相同的用户名。

我遇到的问题是查询不区分大小写,或者可能是数据库中用户名的排序规则(但我现在已经尝试了几十次。唯一似乎能达到预期目的的排序规则是(虽然不是我需要的)latin1_bin 这将允许区分大小写的用户名(例如,Duke、duke、DuKE),如果其他人尝试注册完全相同的用户名,则不允许(例如,如果 DuKE 存在,DuKE 无法注册,但可以注册 duKe)。这很好(我可能稍后会在我的另一个俗气网站上使用它,主要是业余爱好和读书的东西)但现在我需要能够防止注册相同名称但大小写字母不同的用户(例如,如果 'Duke' 已注册,则不允许其他人尝试注册 'duke')。

以上所有内容似乎都是在其他地方发现的重复问题,但我相信我已经尝试了类似问题中提供的所有答案(我已经更改代码数十次以适应答案,但 none 他们给出了不同的结果)。我还尝试在数据库中更改用户名 (当前为 utf8mb4_general_ci).

的排序规则(数十次)

每次我尝试注册脚本时,它都会允许重复的用户名(例如,即使 Duke 已经在数据库中,duke 也会通过)然后(我相信这是预期的)我得到 SQLSTATE[23000]:违反完整性约束:1062 项重复项

如果这里有人可以提供一些关于我做错了什么的见解,我将非常感激!谢谢!代码如下:

<?php

require_once 'dbconfig.php';

if($user->is_loggedin()!="")
{
$user->redirect('home.php');
}

if(isset($_POST['btn-signup']))
{
$uname = trim($_POST['txt_uname']);
$umail = strtolower(trim($_POST['txt_umail']));
$upass = trim($_POST['txt_upass']); 

if($uname=="")  {
    $error[] = "provide username !";    
}
else if($umail=="") {
    $error[] = "provide email id !";    
}
else if(!filter_var($umail, FILTER_VALIDATE_EMAIL)) {
    $error[] = 'Please enter a valid email address !';
}
else if($upass=="") {
    $error[] = "provide password !";
}
else if(strlen($upass) < 6){
    $error[] = "Password must be atleast 6 characters"; 
}
else
{
    try
    {

        $stmt = $DB_con->prepare("SELECT user_name,user_email FROM users 
WHERE user_name = :uname OR LOWER(user_email) = LOWER(:umail)");
        $stmt->execute(array(':uname'=>$uname, ':umail'=>$umail));
        $row=$stmt->fetch(PDO::FETCH_ASSOC);

        if($row['user_name']==$uname) {
            $error[] = "sorry username already taken !";
        }
        else if($row['user_email']==$umail) {
            $error[] = "sorry email id already taken !";
        }
        else
        {
            if($user->register($fname,$lname,$uname,$umail,$upass)) {

                $user->redirect('sign-up.php?joined');
            }
        }
    }
    catch(PDOException $e)
    {
        echo $e->getMessage();
    }
}   
}

?>

试试这个代码

$stmt = $DB_con->prepare("SELECT user_name,user_email FROM users WHERE user_name LIKE :uname OR user_email LIKE :umail ");

$stmt->execute([':uname' => $uname, ':umail' => $umail]);

$found = false;
$inRecord = [];

while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
    $__uname = $row['user_name'];
    $__umail = $row['user_email'];

    if ($__uname == $uname || strtolower($__uname) == strtolower($uname))
    {
        $inRecord['user_name'] = true;
    }

    if ($__umail == $umail || strtolower($__umail) == strtolower($umail))
    {
        $inRecord['user_email'] = true;
    }

    if (count($inRecord) > 0)
    {
        $found = true;
        break;
    }
}

if ($found === true)
{
    if (isset($inRecord['user_name']))
    {
        echo "Username exists!";
    }

    if (isset($inRecord['user_email']))
    {
        echo "Email exists!";
    }
}
else
{
    // register here...
}

只有找到匹配项才会输出。

Username exists! Email exists!