Как предотвратить то же (верхнее или нижнее регистрационное имя) в 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;
}