0

这是我的 PHP 代码 - 它检查用户名是否存在,如果存在,它会添加一个“_”和一个升序数字。

$username从用户输入的用户名开始。

$usernameCopy = $username;
$appendNum = 1;
$userOK = false;
while( $userOK == false )
{
    $query = "SELECT ua.id 
    FROM someDB.users_accounts ua
    WHERE ua.user = '$username'; ";

    $resultID = mysqli_query($linkID, $query) or die("Data not found. USERNAME");
    $numRows = mysqli_num_rows($resultID);
    if( $numRows <> 0)
    {
        //USER ALREADY EXISTS
        $appendNum = $appendNum + 1;
        $username = $usernameCopy . '_' . $appendNum;
    }
    else
    {
        $userOK = true;
    }
}

然后我使用$username.

是否有可能做这样的事情是一个单一的 SQL 查询?

4

3 回答 3

1

我认为这会做到:

$query = "SELECT CONCAT('$username',
                        IFNULL(MAX(CAST(SUBSTR(user, char_length('$username')+1) AS DECIMAL))+1,
                               '') avail_username
          FROM user_accounts
          WHERE user RLIKE '^$username[0-9]*\$'";

这将生成名称,如johnsmith, johnsmith1,johnsmith2等。

可以将它们放在_它们之间,但它会变得更加复杂。

$query = "SELECT IF(maxnum IS NULL,
                  '$username',
                  CONCAT('{$username}_', maxnum+1) avail_username
          FROM (SELECT MAX(CAST(SUBSTR(user, char_length('$username')+2) AS DECIMAL))
                FROM user_accounts
                WHERE user RLIKE '^$username(_[0-9]+)?\$') x";

NULL 测试处理根本没有带有前缀的名称的情况——然后用户获取基本名称。其他情况获取所有名称的最大数字后缀,然后将其加 1 以获得可用后缀。如果 DB 中唯一的名称是基本名称,则后缀将为空字符串,在 CAST 时转换为 0,然后递增为 1。

于 2013-08-27T06:55:14.750 回答
0

对于唯一的用户名,您可以像这样使用。

$firstname = "Testing";
$username=preg_replace('/[^a-zA-Z0-9]/s', '', $firstname). $this->generateRandomString(5);

函数生成随机字符串,

function generateRandomString($length = 5) 
{
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, strlen($characters) - 1)];
    }
    return $randomString;
}
于 2013-08-27T06:52:53.620 回答
0

不是一个直接的答案,但在 PHP 方面你可以尝试这样的事情。

if( $numRows <> 0) //USER ALREADY EXISTS
{
        $username = $usernameCopy . '_' . md5(microtime());
}

并非万无一失,但你明白了。您不太可能发生碰撞,您可以添加一个随机元素以进一步降低这种可能性。话虽如此,正如 Barmar 指出的那样,很少有人愿意输入 32 个额外的字符来以这种方式支持唯一性。所以从可用性的角度来看。

在 SQL 方面,如果您使用 +1 解决方案,问题是您最终将不得不循环测试名称,当名称数量很大时,这将是一个小问题。为避免这种情况并找到最后使用的用户名,您可以按照以下方式执行操作:

SELECT FROM users WHERE username LIKE 'username%' AND date_created = MAX(date_created)

编辑:另一个想法。不知道这有多实用,但您可以有一个用于跟踪受骗者的表格。

username_dupecheck

  • 身份PK
  • 基本名称 varchar
  • last_increment int

在 PHP 中,您可以按如下方式提取基本名称。您必须针对数字超出数字后缀的情况进行检查,并确定这是否可行。

$basename = preg_replace("/\d+$/","",$username);

PS:MySQL 的ON DUPLICATE KEY语法可能会带来其他可能性。

于 2013-08-27T06:59:31.480 回答