Как проверить таблицу, чтобы увидеть, используется ли уже строка? - PullRequest
1 голос
/ 26 марта 2009

Я использую этот код для проверки моего столбца имени пользователя (имя пользователя является основным) в моей таблице userdb, чтобы увидеть, есть ли уже строка. Если его там нет, он добавляет строку, введенную из предыдущей формы, в столбец имени пользователя в моей таблице. Но если он там есть, он говорит: «(Имя пользователя) уже используется!».

Это работает, когда я помещаю запись в столбце имени пользователя, например «Сэм», а затем, когда я ввожу Сэма в предыдущую форму. Но если у меня есть «Sam» в столбце имени пользователя, а затем ввести sam со всеми строчными буквами в предыдущую форму, он отображает дублирующую запись «sam» для ключа 1.

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

$result = mysql_query("SELECT username FROM userdb") or die(mysql_error()); 
$row = mysql_fetch_array( $result );
$checkuser = $row['username'];

if ( $checkuser == $username ) {
    echo "<font color='red'>" .$username. "<font color='black'> is already in use!";
    die(mysql_error());
} else {
    mysql_query("INSERT INTO userdb (username, password) VALUES('$username', '$password' ) ") or die(mysql_error());;
    echo "Data Inserted!";
}

Ответы [ 5 ]

1 голос
/ 26 марта 2009

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

Правильный способ сделать это - указать первичный ключ в имени пользователя и вставить запись, перехватывая код исключения или ошибки, возвращенный из СУБД.

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

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

С точки зрения вашей проблемы с регистром, я бы либо преобразовал все имена пользователей в строчные перед вставкой или проверкой, либо вставил бы смешанную версию и строчную и копию БД, и локальную копию во все проверки.

0 голосов
/ 26 марта 2009

Единственный способ сделать это правильно и избежать состояния гонки * - это попытка вставить данные пользователя и проверить любые ошибки, чтобы определить, является ли ошибка ошибкой дублирующего ключа. Если бы вы использовали PDO (вы должны это сделать), это вызвало бы исключение, которое вы могли бы перехватить и изучить. Я думаю, что вы все еще можете ловить и исследовать ошибки, используя стандартную обработку ошибок PHP, я просто не знаю, как.

* Состояние гонки здесь таково:

  1. Проверьте, уникально ли имя пользователя.
  2. Другой пользователь создает учетную запись с таким именем
  3. Теперь вы пытаетесь создать учетную запись с этим именем для исходного пользователя, что вызывает ошибку.
0 голосов
/ 26 марта 2009

Краткий ответ:

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

$lcusername = strtolower($username);

Затем используйте $ lcusername везде, где вы используете $ username в коде, который вы указали.

Длинный ответ:

Вам не нужно проверять наличие ключа в таблице. Предполагая, что у вас есть атрибут PRIMARY KEY в поле имени пользователя, просто попробуйте внести ваши данные в таблицу (после преобразования их в нижний регистр). Если база данных возвращает ошибку «дубликат ключа», вы знаете, что имя пользователя уже существует, и можете отобразить сообщение об ошибке. Если база данных возвращает, что она успешно вставила строку (возможно, с помощью функции mysql_affered_rows). Это избавляет вас от необходимости делать SELECT перед выполнением INSERT, значительно упрощая ваш код.

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

$lcusername = strtolower($username);

// Escape strings
$esclcusername = mysql_real_escape_string($lcusername);
$escpassword = mysql_real_escape_string($password);

mysql_query("INSERT INTO userdb (username, password) VALUES('$esclcusername', '$escpassword') ");
if (mysql_affected_rows() == -1) {
    // Display error message
} elseif (mysql_affected_rows() == 1) {
    // Yay! Insert successful
} else {
    // Affected rows is 0. Something went wrong
}
0 голосов
/ 26 марта 2009
$result = mysql_query("SELECT count(*) FROM userdb where UCASE(username)=UCASE($checkuser);"

Проверка количества строк в результате.

псевдокод:

If num_rows>0
    Username exists;
0 голосов
/ 26 марта 2009

Измените код на:

strtolower($checkuser) == strtolower($username)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...