生成随机字符串,针对数据库进行检查,然后使用它

时间:2009-11-20 21:33:32

标签: php sql

这是一个在使用随机字符串时不断出现的问题。

这基本上就是这个过程。

  1. 生成随机字符串
  2. 检查数据库中是否已存在
  3. 如果它不使用它,则生成另一个
  4. 那我怎么用PHP做这个呢?

2 个答案:

答案 0 :(得分:5)

为什么不使用GUID让数据库维护它。然后你可以调用存储过程。

答案 1 :(得分:0)

我会使用这个功能,非常简单:

/**
 * Generates a string with random characters taken from the given string
 * of the desided length
 *
 * @param int $length the resulting string length
 * @param string $chars the chars; defaults to all alphanumerics
 * @return string the random string
 * @author Andrea Baron
 */
function rand_string($length,
        $chars = 'qwertyuiopasdfghjklzxcvbnm0123456789') {
    $r = '';
    $cm = strlen($chars)-1;
    for($i=1; $i<=$length; ++$i) {
        $r .= $chars[mt_rand(0, $cm)];
    }

    return $r;
}

然后你可以做这样的事情

$used = $db->prepare('SELECT EXISTS(SELECT string FROM table WHERE string = ?)');
do {
    $string = rand_string(32);
    $used->execute(array($string));
    $exists = $used->fetch(PDO::FETCH_NUM);
    $used->closeCursor();
} while($exists && $exists[0]);

$ins = PP::$db->prepare('INSERT INTO table SET string=?');
$ins->execute(array($string));

如果你使用PDO和MySQL;我将字符串字段设置为主键,或者如果在辅助字段上则设置HASH索引;或者更简洁,也许不那么强大:

do {
    $string = rand_string(32);
    $exists = PP::$db->exec('INSERT INTO a SET string='.PP::$db->quote($string));
} while(!$exists);

这是因为exec()在没有错误的情况下返回受影响的行数,如果有错误则返回false,在这种情况下是重复的键值。

或者,作为替代方案,您可以添加时间戳并忘记检查。像:

$string = rand_string(8).time();

具有重复标识符的概率每秒重置一次,并且如您所见,在37 ^ 8或3.5E12中为8个字符。