一文解決PHP中生成隨機數(shù)遇到的重復(fù)問題
場景描述
項目開發(fā)中很多地方需要用到唯一編碼,比如說訂單、卡券、邀請碼等等。這些編號是需要嚴(yán)格保證唯一性的,因為如果系統(tǒng)中訂單的編號存在倆一模一樣的,那造成很多數(shù)據(jù)的錯亂。實現(xiàn)唯一編碼的方式也是很多的,一般是通過底層的一些隨機函數(shù) mt_rand() uniqid()等等。
探索實現(xiàn)方式一
public static function uniqidNumberCode($length = 10)
{
$time = time() . '';
if ($length < 10) $length = 10;
$string = ($time[0] + $time[1]) . substr($time, 2) . rand(0, 9);
while (strlen($string) < $length) $string .= rand(0, 9);
return $string;
}
上面這個是用的三方包中的生成方式。參數(shù)中可以設(shè)置當(dāng)前生成的編號長度。以當(dāng)前時間的時間戳為基礎(chǔ)數(shù)據(jù),計算出10位隨機數(shù)字。當(dāng)我們單次去執(zhí)行的時候,生成的數(shù)據(jù)是非常正確的。

但是,當(dāng)我們需要批量的生成一堆的隨機編號的時候

可以發(fā)現(xiàn),以肉眼可見的速度出現(xiàn)了一堆的重復(fù)數(shù)據(jù)。
探索方式二
請教了一下chatgpt,讓它生成一個方法如下
function generateUniqueNumber($length = 10) {
// 生成一個唯一標(biāo)識符
$uniqueId = uniqid();
// 移除標(biāo)識符中的前綴并截取前10位
$uniqueNumber = substr($uniqueId, strlen($uniqueId) - 10);
return $uniqueNumber;
}
還是測試一下批量生成的場景。

雖然生成的數(shù)據(jù)看著正確,但是數(shù)據(jù)格式不是怎么的讓人可以接受。還是希望生成10位純數(shù)字的。
探索方式三
再一次請教了一下chatgpt。
function generateUniqueNumber($length = 10) {
// 獲取當(dāng)前時間戳
$timestamp = time();
// 生成一個隨機數(shù),確保足夠的隨機性
$randomNumber = mt_rand(100, 999);
// 組合時間戳和隨機數(shù),并截取前10位
$uniqueNumber = substr($timestamp . $randomNumber, 0, 10);
return $uniqueNumber;
}

這下可好,生成的數(shù)據(jù)完全的毫無區(qū)別了。看來雖然gpt能幫助我們很多,但是選擇還是需要謹(jǐn)慎些。一些關(guān)鍵邏輯如果出現(xiàn)嚴(yán)重問題可是不太好交差的。
探索方式四
我們嘗試用php底層的生成隨機數(shù)的函數(shù) mt_rand() 對數(shù)據(jù)進(jìn)行生成。
function generateUniqueNumber($length = 10) {
$uniqueNumber = mt_rand(1000,9999);
return $uniqueNumber;
}
發(fā)現(xiàn)在某些特殊的情況下還是會出現(xiàn)重復(fù)數(shù)據(jù)的可能。
探索實現(xiàn)方式二
//生成10位隨機數(shù)
function generateUniqueNumber() {
list($usec, $sec) = explode(' ', microtime());
$seed = (float) $sec + ((float) $usec * 100000);
mt_srand($seed);
return mt_rand(1000000000,9999999999);
}
在mt_rand函數(shù)的基礎(chǔ)上,生成隨機數(shù)之前。對隨機數(shù)發(fā)生器的種子也用毫秒的值進(jìn)行重新生成。然后再將mt_rand函數(shù)的區(qū)間盡量去放大。
這樣基本可以滿足需求,但是卻是無法保證萬無一失。程序這東西嘛,保證數(shù)據(jù)準(zhǔn)確才是永遠(yuǎn)的追求。為了準(zhǔn)確,我又給數(shù)據(jù)庫的唯一編號字段加了唯一索引。這樣就在數(shù)據(jù)庫層面上保證了生成的編號肯定是唯一的。
當(dāng)然,如果在生成編號以后,程序再主動去數(shù)據(jù)庫中查詢一遍字段是否存在,然后再執(zhí)行下面的業(yè)務(wù)這就更好了。
以上是整個分析過程,不足之處或者更好方案歡迎給我留言。
以上就是一文解決PHP中生成隨機數(shù)遇到的重復(fù)問題的詳細(xì)內(nèi)容,更多關(guān)于PHP中生成隨機數(shù)遇到重復(fù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
PHP創(chuàng)建XML的方法示例【基于DOMDocument類及SimpleXMLElement類】
這篇文章主要介紹了PHP創(chuàng)建XML的方法,結(jié)合實例形式分析了php基于DOMDocument類及SimpleXMLElement類創(chuàng)建xml文件的具體步驟與相關(guān)實現(xiàn)技巧,需要的朋友可以參考下2019-09-09
thinkphp autoload 命名空間自定義 namespace
這篇文章主要介紹了thinkphp autoload 命名空間自定義 namespace的相關(guān)資料,需要的朋友可以參考下2015-07-07
使用PHPStorm+XDebug搭建單步調(diào)試環(huán)境
由于 PhpStorm 不像 Zend 公司為 Zend Studio 那樣配套集成了很多開發(fā)部件,包括解釋器、調(diào)試器、虛擬機、服務(wù)器、開發(fā)框架等等。因此,配置 PhpStorm 開發(fā)環(huán)境相對較繁瑣,有很多需要注意的地方。2017-11-11

