我编写了一个函数来生成一个包含7个字母数字字符的随机字符串,然后将其插入到mysql数据库中。
以下是代码:
function getRandomID(){
$tmp ="";
$characters=array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","1","2","3","4","5","6","7","8","9");
for($i=0;$i<7;$i++)
$tmp.=$characters[rand(0,count($characters)-1)];
return $tmp;
}
我没有检查重复项atm,因为我预计数据库中的条目不会超过1000个,并且我已经计算出这个函数可以返回(35)^ 7 = 64,339,296,875个可能的值。
我正在本地和现场服务器上测试它。
问题出在最后一小时,这个函数生成了两次重复值。
我在数据库中找到了3个条目,所有条目都有相同的随机字符串。
我不知道是什么导致这种情况,因为我之后尝试了很多次而且问题不可重现。
有没有人知道这里会发生什么?
非常感谢提前
答案 0 :(得分:1)
使用“meh,这不会发生”的思维模式设计你的代码是一个非常冒险的游戏,只需正确执行一次,这样你就不必多次回到你的代码来快速修复小事情喜欢这些。
重复检查,你会坚实。
您可以创建类似
的功能function stringExists($string)
{
...
return $boolValue;
}
您可以轻松创建一个while循环,在生成旧字符串时生成新字符串。
$duplicate = true;
while($duplicate)
{
$newString = getRandomId();
$duplicate = !stringExists($string);
}
// Work with the newest string that is not a duplicate.
如果你真的想进入它
如果您想了解可能导致问题的原因,您可以查看兰特的documentation。此外,如果我们不知道有多少条目,则3个条目没有任何意义。有时“随机”功能并不像人们想象的那样随机,有时候某些编程语言中的随机函数总是可用的,但在它们变得“真正”随机之前需要某种启动。
插入的时间也可能是问题的一部分,互联网上有很多线程,比如堆栈溢出中的this,它有一些可能影响你的“随机”的有趣点。
无论是否真实,未在评论中指出,您可以非常肯定在相关主题和主题中找到问题的答案。
简短回答:不要考虑并重复检查,这很容易。
请注意,您当然应该首先使您的ID成为数据库中的UNIQUE约束。
答案 1 :(得分:0)
srand()
为随机数生成器播种。getRandomID()
函数,而是代码中的其他内容正在重复使用以前的值。答案 2 :(得分:0)
如果需要在数据库中输入唯一数据,可以使用PHP函数uniqid()
。 (http://ca3.php.net/uniqid)
该函数根据当前的微秒生成更多的随机字符串。所以理论上它是独一无二的。
但是,在插入之前检查总是很好。或者至少在该字段上添加UNIQUE
索引。
答案 3 :(得分:0)
你可以这样做:
function randomString($length, $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") {
$string = "";
$charsLength = strlen($chars);
for ($i = 0; $i < intval($length); $i++) {
$string .= $chars[rand(0, $charsLength - 1)];
}
return $string;
}
上面的函数将从给定的字符生成给定长度的随机字符串。这使得它比您的实现更灵活,如果您需要在以后的其他环境中使用它。
然后你可以做这样的检查:
$id = null;
do {
$id = randomString(7);
} while (!isUnique($id));
// do your insert here. You need to write your isUnique, so that it checks if
// the given string is unique or not.