如何检查表以查看字符串是否已被使用?

时间:2009-03-26 02:43:01

标签: php mysql string comparison

我正在使用此代码检查我的userdb表中的用户名列(用户名是主要的),以查看该字符串是否已存在。如果它不存在,那么它将从前一个表单输入的字符串添加到我的表中的用户名列中。但如果它存在,那么它说“(用户名)已经在使用!”。

当我在“Sam”这样的用户名栏中输入一个条目,然后当我将Sam输入到上一个表单中时,这是有效的。但是,如果我在用户名列中有“Sam”,然后将所有小写的sam输入到上一个表单中,则会为键1显示重复条目“sam”。

我只是想说这个字符串已经被使用了,无论我输入上一个表格的是什么样的外壳。

$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 个答案:

答案 0 :(得分:1)

你不应该这样做,因为它可能导致竞争条件。如果在您的支票和插入之间,其他人将该用户名插入表格中,就会发生这种情况。

正确的方法是在用户名上使用主键并插入记录,捕获从DBMS返回的异常或错误代码。

如果用户名已存在,则不会再次插入,您将收到错误。

如果它不存在,它将被插入,你将不会得到任何错误。

就你的套管问题而言,我要么在插入或检查之前将所有用户名转换为小写,要么在所有检查中插入混合大小写版本和小写DB副本和本地副本。

答案 1 :(得分:0)

将代码更改为:

strtolower($checkuser) == strtolower($username)

答案 2 :(得分:0)

$result = mysql_query("SELECT count(*) FROM userdb where UCASE(username)=UCASE($checkuser);"

检查结果中的行数。

伪代码:

If num_rows>0
    Username exists;

答案 3 :(得分:0)

简短的回答是:

如果您希望用户名不区分大小写,则需要以不区分大小写的方式将它们存储在数据库中。首先将给定的用户名转换为全部小写(或全部大写)。

$lcusername = strtolower($username);

然后在您提供的代码中使用$ username的地方使用$ lcusername。

答案很长:

您无需检查表中是否存在密钥。假设您在用户名字段上有一个PRIMARY KEY属性,只需将数据尝试到表中(在将其转换为小写后)。如果数据库返回“重复键”错误,您知道用户名已存在,您可以显示错误消息。如果数据库返回它成功插入行(可能通过使用mysql_affected_rows函数)。这使您无需在执行INSERT之前执行SELECT,从而大大简化了代码。

您还应该转义要插入表中的所有字符串,以帮助避免潜在的安全漏洞。

$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
}

答案 4 :(得分:0)

正确执行此操作并避免竞争条件*的唯一方法是尝试插入用户的数据并检查所有错误以查看错误是否是重复键错误。如果你正在使用PDO(你应该)它会抛出一个你可以捕获并检查的异常。我认为你仍然可以使用PHP的标准错误处理陷阱和检查错误,我只是不确定如何。

*这里的竞争条件是:

  1. 检查用户名是否唯一,是。
  2. 另一位用户使用该用户名
  3. 创建帐户
  4. 您现在尝试为原始用户创建一个具有该用户名的帐户,这会导致错误。