Как предотвратить то же (верхнее или нижнее регистрационное имя) в PHP?

Я могу запретить нескольким пользователям регистрироваться с одинаковым именем пользователя с помощью кода ниже:

$sqlusercheck = "SELECT (SELECT COUNT(row_username) FROM table_users WHERE row_username = :username LIMIT 1) as checkusername";
$stmt = $database->prepare($sqlusercheck);
$stmt->bindValue(':username', $username);
$stmt->execute();
$row = $stmt->fetch();

if ($row->checkusername > 0) {
    $this->error[] = "This username is already taken.";
    $success = false;
}

Итак, если в базе данных есть Abc, пользователь не может взять имя пользователя Abc, но он все равно может зарегистрироваться с помощью Abc, Abc, Abc и т.д., что я хотите предотвратить.

В качестве возможного решения я не хочу использовать strtolower() имя пользователя. Вместо этого я хочу, чтобы пользователь Abc заходил в систему с его паролем независимо от того, написал ли он вход для входа Abc, Abc, Abc и т.д.

Зачем мне это нужно?

Я заметил, что пользователь может зарегистрироваться с именем пользователя Abc на своем компьютере. Но когда он хочет войти в систему на своем мобильном устройстве, устройство автоматически запустит первую букву, а пользователь не сможет войти в систему. Или наоборот.

Итак, почему я не хочу strtolower()?

Потому что пользователи также хотят, чтобы они показывались как Abc, и так специально зарегистрировались. Таким образом, их имена пользователей будут показаны по мере их регистрации.

Ответ 1

В этом случае вы можете воспользоваться функцией mysql LOWER() и php strtolower(). (Не беспокойтесь, только когда вы проверяете доступность.)

$sqlusercheck = "SELECT (SELECT COUNT(row_username) FROM table_users WHERE LOWER(row_username) = :username LIMIT 1) as checkusername";
$stmt = $database->prepare($sqlusercheck);
$stmt->bindValue(':username', strtolower($username);

Если вы измените свой запрос таким образом, он сделает оба значения в нижнем регистре и сравните, если они будут одинаковыми.

Если они есть, появится ваша ошибка.

Если это не так, он будет добавлен в вашу базу данных в качестве способа его ввода.

Примечание. Для входа в систему, как описано, вы должны внести те же изменения в свой логин.

Ответ 2

MySQL

Это зависит от сортировки таблицы. Если он заканчивается на _ci, тогда он уже нечувствителен к регистру, когда вы выполняете недвоичное сравнение строк, причем по умолчанию они уже. Однако, если он заканчивается на _cs или _bin, тогда он чувствителен к регистру.

Если ваша сортировка в таблице чувствительна к регистру, и вы хотите сделать запрос, нечувствительный к регистру, вы можете добавить COLLATE к запросу, например:

... WHERE row_username COLLATE collation_you_want_ci = :username LIMIT 1

Если вы хотите сделать запрос, чувствительный к регистру, при сортировке _ci, не прибегая к преобразованию строк в верхний или нижний регистр, вы можете использовать BINARY:

... WHERE BINARY row_username = :username LIMIT 1

PostgreSQL

В PostgreSQL значение по умолчанию чувствительно к регистру для сравнения строк. Вы можете использовать ILIKE, ~* или LOWER, но обратите внимание, что они имеют потенциальные последствия для производительности ваших индексов. Используйте тип данных citext или функциональный индекс.

Ответ 3

Используйте mysql LOWER в вашем запросе и используйте strtolower() Функция PHP при связывании param: -

$sqlusercheck = "SELECT (SELECT COUNT(row_username) FROM table_users WHERE LOWER(row_username) = :username LIMIT 1) as checkusername";
$stmt = $database->prepare($sqlusercheck);
$stmt->bindValue(':username', strtolower($username)); // use strtolower function
$stmt->execute();
$row = $stmt->fetch();

Надеюсь, это поможет вам:)

Ответ 4

Вы можете попробовать следующее решение:

$sqlusercheck = "SELECT (SELECT COUNT(row_username) FROM table_users WHERE LOWER(row_username) = :username LIMIT 1) as checkusername";
$stmt = $database->prepare($sqlusercheck);
$stmt->bindValue(':username', strtolower($username));
$stmt->execute();
$row = $stmt->fetch();

if ($row->checkusername > 0) {
    $this->error[] = "This username is already taken.";
    $success = false;
}