【问题标题】:How do I check a table to see if a string is already in use?如何检查表以查看字符串是否已在使用中?
【发布时间】:2009-03-26 02:43:01
【问题描述】:

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

当我在用户名列中输入一个条目(例如“Sam”)然后在之前的表单中输入 Sam 时,此方法有效。但是如果我在用户名列中有“Sam”,然后在前面的表单中输入全小写的 sam,它会显示 Duplicate entry 'sam' for key 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!";
}

【问题讨论】:

    标签: php mysql string comparison


    【解决方案1】:

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

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

    如果用户名已经存在,则不会再次插入,您会发现错误。

    如果它不存在,它将被插入并且不会出错。

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

    【讨论】:

      【解决方案2】:

      将代码改为:

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

      【讨论】:

        【解决方案3】:
        $result = mysql_query("SELECT count(*) FROM userdb where UCASE(username)=UCASE($checkuser);"
        

        检查结果中的行数。

        伪代码:

        If num_rows>0
            Username exists;
        

        【讨论】:

          【解决方案4】:

          简短的回答是:

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

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

          【讨论】:

            【解决方案5】:

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

            *这里的比赛条件是这样的:

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-08-21
              • 2021-11-10
              • 1970-01-01
              相关资源
              最近更新 更多