php - 创建随机数并确保它是唯一的
问题描述
在我的系统中,每个客户都有自己的文件夹,其名称由 rand() 函数生成。
我想确保 $random 变量的值始终保持唯一。我创建了下面的代码,它应该:
- 生成随机数
- 检查具有唯一值的文件夹是否存在
- 如果存在生成新号码
- 如果不存在具有随机值名称的 mkdir
但我不确定它是否正常工作并且是执行上述步骤的有效方式。
$random = rand(pow(10, 3-1), pow(10, 3)-1);
$path_validator = 'build/'.$random;
if(is_dir($path_validator)) {
$random = rand(pow(10, 3-1), pow(10, 3)-1);
}
else
{
mkdir('build/crm/'.$random, 0777);
}
$random
必须是随机的 3 位数字
解决方案
预选赛
1)因为您已经在检查该值是否存在,所以就其比较器而言,它的唯一性并不重要。
2)因为你只想要一个“3位”数字,所以只有1000种可能性,这使得对唯一值的请求在事物的计算规模上毫无意义。
答案
因此您可以简单地使用mt_rand
,因为:
许多旧 libcs 的随机数生成器具有可疑或未知的特性并且速度很慢。mt_rand() 函数是旧 rand() 的直接替代品。它使用具有已知特性的随机数生成器,使用 » Mersenne Twister,生成随机数的速度比 libc rand() 提供的平均速度快四倍。
因为您正在寻找一组数字,您可以在mt_rand
函数调用中简单地设置这个范围。
因此:
代码
// Below lines are only to show the parts to generate $random var.
// $random = mt_rand(0,999); //generate random number between 0 and 999
// $random = sprintf('%03d', $random); //forces value to 3-digits. ie: 005
//
// Real code begins here:
do {
$random = sprintf('%03d',mt_rand(000,999));
$path_validator = 'build/'.$random;
clearstatcache(); // the directory checker result is cached.
}
while(is_dir($path_validator) || !mkdir('build/crm/'.$random, 0777));
(另见sprinf
)
笔记:
- 范围很小——1000 次迭代是微不足道的。平方这个数字。
0777
制作具有特权的文件夹时要格外小心。- 非常小心文件夹竞争条件,PHP 可以检查文件夹是否存在,然后在它被并行* PHP 进程(例如另一个实例)创建之前发现它不存在。
- 检查文件夹是否存在时,请小心使用 PHP缓存结果。
- 虽然
mt_rand
比随机性更大rand
,但两个用户都将生成相同的 3 位数值的可能性仍然相对较高。被警告!!
推荐阅读
- docker - 使用 dotnet:2.1-sdk 在 docker 容器中构建 dotnet 失败
- enterprise-architect - Sparx EA VBScript。如何“someInformationFlow.ConveyedItems.AddNew”?
- winforms - 配对 BLE 设备
- string - POSIX sh:如何仅使用 shell 将整个文件读入单个字符串,同时在原始文件中保留空格和换行符?
- javascript - 从颜色选择器 Three.js 中选择颜色
- git - 如何从 .gitignore 子文件夹中排除所有扩展名(但不包括 PHP 和 JS)?
- php - PHP 如何在 csv 文件中打印数组?
- mariadb - MariaDB 生成列 vs. 内置函数,哪个更快?
- elasticsearch - 估计弹性搜索索引大小的最佳方法
- c# - 如何从实体框架数据库中获取包含在类中的项目列表