这是一个在使用随机字符串时不断出现的问题。
这基本上就是这个过程。
那我怎么用PHP做这个呢?
答案 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个字符。