防止重复的用户名在用户名后添加序列号

时间:2012-10-07 10:50:31

标签: php sql

我正在尝试实施Facebook注册。它工作,我收回了我需要的所有数据。现在我想为用户分配一个用户名,如下所示:

$username = ''.$first_name.'.'.$lastname.'';

问题是我不知道具有相同名称和姓氏的用户是否会注册到该网站,我想检查是否使用了用户名并将序列号添加到基本的$ username(facebook做同样的事情),像这样:

name.lastname
name.lastname.1
name.lastname.2
etc

我尝试过:

$temp_username = ''.$first_name.''.$last_name.'';
$check_username = mysql_query("SELECT username FROM users WHERE username = '$temp_username'");
$num_rows = mysql_num_rows($check_username);
if ($num_rows == 0){
    $username = strtolower($temp_username);
} else {
    $username = strtolower(''.$temp_username.'.'.$num_rows.'');
}

但当然它不起作用,因为只有一个用户拥有该用户名。

编辑* * *这是我修复它的方式(感谢zander):

        $temp_username = ''.$first_name.''.$last_name.'';
        $num_rows = mysql_num_rows(mysql_query("SELECT username FROM users  WHERE username = '$temp_username' OR username LIKE '$temp_username%' "));
        $username = strtolower(''.$temp_username.'.'.$num_rows.'');

8 个答案:

答案 0 :(得分:2)

$num_rows = mysql_num_rows(mysql_query("SELECT username FROM users WHERE username = '$temp_username' OR username LIKE '$temp_username.%' "));将返回您实际期望的行数。然后,使用$username = strtolower(''.$temp_username.'.'.$num_rows.'');完成它。不需要循环。

答案 1 :(得分:2)

以下SELECT确定具有最高编号的用户(如果有)

select max(reverse(SUBSTRING(reverse(username), 1, LOCATE('.', reverse(username))-1))) trail 
  from users
 where username like 'John.Smith.%';

SQL Fiddle Demo

像这样添加到PHP

...
if ($num_rows == 0){
    $username = strtolower($temp_username);
} else {
   ... query for the max number here
   ... concatenate the username with the max number 
}

啊,最后但并非最不重要。确保您的代码不易受SQL注入攻击。使用绑定参数。这个答案的好开头是:Best way to defend against mysql injection and cross site scripting

答案 2 :(得分:1)

有许多现有答案正确建议在WHERE子句中使用LIKE运算符。但是有一个关键问题是现有的答案都没有解决。

两个人可能会尝试在相同(或几乎相同)的时间添加相同的用户名。每个人都会选择与该名称相似的现有用户名的计数,并且每个用户名都将生成相同的数字后缀,并且您仍然会获得重复项。

我既不是mysql开发人员也不是php开发人员,因此我不会提供特定语法的方法。

您需要确保您的用户表使用InnoDB storage engine。您的代码需要:

  1. START TRANSACTION

  2. SELECT FOR UPDATE以确保只有一个人可以获得计数 特定时间的特定用户名

  3. 插入新用户

  4. 提交您的交易。

  5. 有关详细信息,请参阅Select for update

答案 3 :(得分:0)

请改用此代码:

$check_username = mysql_query("SELECT username FROM users WHERE username = '$temp_username' OR username LIKE  '$temp_username.%' ");

示例这将匹配:

johnsmith或joshnsmith.X其中x将是1,2,3 ......等等

答案 4 :(得分:0)

DB Dump

CREATE TABLE Users (
  `username` varchar(255) PRIMARY KEY,
  `firstname` varchar(255),
  `lastname` varchar(255)
);

INSERT INTO Users (`username`, `firstname`, `lastname`) VALUES (
  'praveen.kumar', 'Praveen', 'Kumar'
),(
  'praveen.kumar.1', 'Praveen', 'Kumar'
),(
  'praveen.kumar.2', 'Praveen', 'Kumar'
);

现在对SQL,我们可以这样做:

SELECT *
FROM `Users`
WHERE `username` LIKE "praveen.kumar%"
ORDER BY `username` DESC

给出一个输出:

+-----------------+-----------+----------+
|        USERNAME | FIRSTNAME | LASTNAME |
+-----------------+-----------+----------+
| praveen.kumar.2 |   Praveen |    Kumar |
| praveen.kumar.1 |   Praveen |    Kumar |
|   praveen.kumar |   Praveen |    Kumar |
+-----------------+-----------+----------+

你可以通过这种方式得到最新版本:

SELECT *
FROM `Users`
WHERE `username` LIKE "praveen.kumar%"
ORDER BY `username` DESC
LIMIT 1

PHP代码

<?php
    # Outputs the largest number with that username.
    $nextUser = substr($userNameFromDB, strrpos($userNameFromDB, "."));
    $nextUser++;
?>

SQL小提琴:http://sqlfiddle.com/#!2/ad149/1

答案 5 :(得分:0)

使用count()功能和like运算符:

$check_username = mysql_query("
    SELECT count(username) 
    FROM users 
    WHERE username like '$temp_username%'
");

它将返回现有名称的数量。无需致电mysql_num_rows

答案 6 :(得分:0)

您应该使用count()函数

$query = mysql_query("
  SELECT count(user_name) cnt
    FROM users 
    WHERE username = '$just_registered_username'
");

然后使用

获取结果
$row = sql_fetchrow($query);

然后将用户数量计为

$next_index = $row->cnt;

然后将其附加到新用户名

$new_username = "{$just_registered_username}.{$next_index}";

不要忘记在最终代码中添加注释。 还尝试使用PDO进行数据库访问。

答案 7 :(得分:-1)

如果要查找不存在的用户名,则必须尝试组合,直到找到不存在的用户名。

因此,循环直到找到不存在的名称:

$temp_username = $first_name . $last_name;
$i=1;
$found = false;
while(!$found) {
  $check_username = mysql_query(
     "SELECT username FROM users WHERE username = '$temp_username'");
  $found = mysql_num_rows($check_username);
  if ($found){
    $username = strtolower($temp_username);
  }
  else{
    $temp_username = $first_name . $last_name . '.' . $i;
    $i++
  }
}