インターネット上で一意の ID を生成するコードを見たことがありますが、この PHP のコードは ID を生成するときに非常に繰り返しが多いとコメントしています。
class Idwork{ const debug = 1; static $workerId; static $twepoch = 1361775855078; static $sequence = 0; const workerIdBits = 4; static $maxWorkerId = 15; const sequenceBits = 10; static $workerIdShift = 10; static $timestampLeftShift = 14; static $sequenceMask = 1023; private static $lastTimestamp = -1; public function __construct($workId) { if ($workId > self::$maxWorkerId || $workId < 0) { throw new Exception('worker Id can\'t be greater than 15 or less than 0'); } self::$workerId = $workId; } public function timeGen() { //获得当前时间戳 $time = explode(' ', microtime()); $time2 = substr($time[0], 2, 3); $timestramp = $time[1] . $time2; return $time[1] . $time2; } public function tilNextMillis($lastTimestamp) { $timestamp = $this->timeGen(); while ($timestamp <= $lastTimestamp) { $timestamp = $this->timeGen(); } return $timestamp; } public function nextId() { $timestamp = $this->timeGen();//1452043798718 if (self::$lastTimestamp == $timestamp) { self::$sequence = self::$sequence + 1 & self::$sequenceMask; if (self::$sequence == 0) { $timestamp = $this->tilNextMillis(self::$lastTimestamp); } } else { self::$sequence = 0; } if ($timestamp < self::$lastTimestamp) { throw new Excwption('Clock moved backwards. Refusing to generate id for ' . (self::$lastTimestamp - $timestamp) . ' milliseconds'); } self::$lastTimestamp = $timestamp; $nextId = sprintf('%.0f', $timestamp) - sprintf('%.0f', self::$twepoch) | self::$workerId << self::$workerIdShift | self::$sequence; return $nextId; }}$Idwork = new Idwork(1);$a = $Idwork->nextId();
function get_order_sn(){ mt_srand((double) microtime() * 1000000); return date('Ymd') . str_pad(mt_rand(1, 99999), 4, '0', STR_PAD_LEFT);}echo get_order_sn();
PHP を使用してください組み込み関数 uniqid
参考: http://php.net/manual/zh/function.uniqid.php
echo uniqid(), PHP_EOL;echo uniqid(), PHP_EOL;
568c83e69c671568c83e69c671
function get_order_sn(){ mt_srand((double) microtime() * 1000000); return date('Ymd') . str_pad(mt_rand(1, 99999), 4, '0', STR_PAD_LEFT);}echo get_order_sn(), PHP_EOL;echo get_order_sn(), PHP_EOL;
201601063753201601063753は明らかにできませんテスト自体に合格します テスト
$Idwork = new Idwork(1);echo $Idwork->nextId(), PHP_EOL;echo $Idwork->nextId(), PHP_EOL;$test = new Idwork(1);echo $test->nextId(), PHP_EOL;echo $test->nextId(), PHP_EOL;は独自のテスト
コードの最初の部分を Idwork.php とすると、
$mch = curl_multi_init();for($i=0; $i<4; $i++) { $ch = curl_init('http://localhost/Idwork.php'); curl_multi_add_handle($mch, $ch);}$running = NULL;do { usleep ( 10000 ); curl_multi_exec ( $mch, $running );} while ( $running > 0 );
8015005880150059801500588015005980150058801500598015005880150059801500588015005980150058801500598015005880150059は明らかに get_order_sn メソッドの同時実行テスト
date('YmdHis') に合格できません。秒を取得する、繰り返しの確率は比較的小さい
方法を紹介しますが、桁の問題は調整次第です
長さを制限しない方法もありますの数値を使用できるメソッド(年月日と10秒がわかる+乱数)(26桁)
$order_sn = date('YmdHis').substr(time() ,-5).substr(microtime (),2,5).rand(10,99);
利点:
1. データベースを操作する必要がなく、パフォーマンスが高い。
2. 注文が生成されるおおよその時間を確認するのはそれほど難しくありません。
3. 複数のリクエストを処理できるのはプログラムだけです。 100万分の1秒以内に同時に注文番号を生成すると、同時に発生する10から99までの乱数が同じになり、重複した注文番号が表示されます。
2016010612111453474171874820160106121114534741718783201601061211145347417187832016010612111453474171871920160106121114534741718730201601061211145347417187772016010612111453474171871320160106121114534741718782
まだ同時実行テストに合格できません
com_create_guid のみがグローバル一意識別子 (GUID) を生成します
重複がないことを確実に保証できます同じサーバー内
複数のサーバー間で重複があるかどうかは、テストしないと確認できません
GUID はグローバルに一意であることがわかっています
com_create_guid のみがグローバルに固有識別子(GUID)
同一サーバー内で重複がないことが確実に保証できる
複数のサーバー間で重複があるかどうかはテストしないと確認できません
そしてGUID世界で唯一の番号として知られています
com_create_guid のみがグローバル一意識別子 (GUID) を生成します
確実に存在することを保証できます同一サーバー内での重複はありません
複数のサーバー間で重複があるかどうかはテストしないと確認できません
そして GUID は世界的に一意であると言われています
echo uniqid(), PHP_EOL;echo uniqid(), PHP_EOL;
568c83e69c671568c83e69c671
function get_order_sn(){ mt_srand((double) microtime() * 1000000); return date('Ymd') . str_pad(mt_rand(1, 99999), 4, '0', STR_PAD_LEFT);}echo get_order_sn(), PHP_EOL;echo get_order_sn(), PHP_EOL;
201601063753201601063753明らかに独自のテストに合格することはできません
$Idwork = new Idwork(1);echo $Idwork->nextId(), PHP_EOL;echo $Idwork->nextId(), PHP_EOL;$test = new Idwork(1);echo $test->nextId(), PHP_EOL;echo $test->nextId(), PHP_EOL;は合格できますそれ自体をテストします
echo uniqid(), PHP_EOL;echo uniqid(), PHP_EOL;function get_order_sn(){ mt_srand((double) microtime() * 1000000); return date('Ymd') . str_pad(mt_rand(1, 99999), 4, '0', STR_PAD_LEFT);}echo get_order_sn(), PHP_EOL;echo get_order_sn(), PHP_EOL;
com_create_guid のみがグローバル一意識別子 (GUID) を生成します
同じサーバー内で繰り返されないことを確実に保証できます
複数のサーバー サーバー間で重複があるかどうかはテストしないと確認できません
GUID は世界で唯一と言われています
com_create_guid のみがグローバル一意識別子 (GUID) を生成します
同一サーバー内で重複がないことが保証できます
複数のサーバー間で重複があるかどうか
また、GUID は世界で唯一であると言われています
1 つの操作で 2 つの ID が生成される場合、少なくとも 2 つの ID が異なることが保証される必要があります。
これが保証できない場合、2 つのリクエストで取得された ID が異なることをどのように確認できますか? ?
Idwork クラスは、1 回のプログラム実行では重複がないことを保証できますが、複数の実行では重複が発生します
com_create_guid は確かに非常に長いですが、このため、一意であることが保証されています
常識的に考えて、これまでに出現したことのない ID を取得したい場合は、それが出現した ID シーケンスに含まれていないことを確認する必要があります
そして、この ID シーケンスは、表示されたデータは公開の場所に保存する必要がありますが、共有の競合を防ぐためにも必要です
したがって、最良の選択はデータベースの自動インクリメント フィールドを使用することです
皆さん、熱心な回答とありがとうございました。たくさんの知識を学びました