ホームページ  >  記事  >  バックエンド開発  >  PHPで一意で反復しない文字列を生成する方法

PHPで一意で反復しない文字列を生成する方法

藏色散人
藏色散人オリジナル
2021-07-03 11:40:433432ブラウズ

php が文字列を生成する唯一の非反復方法: 1. 現在のタイムスタンプを md5 で暗号化し、最初の 6 桁をインターセプトします; 2. データベース bigint を使用してフィールドを自動インクリメントし、それを次のように変換します。長さを短くするには62。

PHPで一意で反復しない文字列を生成する方法

この記事の動作環境:Windows 7系、PHPバージョン 7.1 、DELL G3 コンピューター

PHP はどのようにして 6 桁の非繰り返し文字列を生成しますか?

PHP は 6 桁の非反復文字列 (UUID と同様) を生成します

考慮する必要があります:

1. 重複はありません。

2. セキュリティ。

【 不建议使用啥敏感的数据作为订单生成规则(例如:用户UID,订单自增ORDER_ID等),以为会暴露网站一些敏感信息】

3.大規模なランダムコードは使用できません。


why?

    まず最初に、「プログラミング言語のランダム性は本当にランダムでしょうか?」と尋ねますが、少なくとも PHP ではそれができないと自信を持って言えます。 「非反復」の原則が発生する
  1. #注文数量が 1,000 万回に達すると、注文コードを生成するたびに 1,000 万個の履歴データを比較する必要があります。 500万を超えると、データベースの最適化(パーティショニングを使用したり、インデックスを作成したりする単純な処理)に時間を費やす必要があります。ただし、実用的な要件は高く、メインデータベースでの運用が必要になる場合があります。どれだけ苦痛ですか?もちろん、データベースのリアルタイム読み取りおよび書き込みのための他の最適化方法もありますが、ここでは紹介しません)。
  2. 4. 同時実行を防止します。

5. 制御桁数。

why?
1. 便于查询检索
2 位数控制到 10-20位即可,当然网上将的是10~15缘由是利于输入,对于输入太长做好用户体验就好(新增复制订单按钮)

6. ビジネス上の重要性を持たせるようにしてください (会社のビジネスに基づいて、必須ではありません)

【当你业务比较庞大时候,或者后期有大规模的扩充时,建议考虑下订单的生成意义,根据公司的业务做调整。举个最简单的例子:"一个卖化妆品的商城,你需要根据订单来源来(pc/移动)来生成报表,这时候可能需要"】

7. 解決策

// 类似生成 UUID ,不依赖外部流水号,完全靠时间戳和随机数生成订单号无法避免冲突,
// 所以必须引入外部的流水号生成机制。或使用数据库,或使用APC之类的缓存。
// 用APC之类的缓存存在一个问题,就是无法持久保持数据,服务器重启或者PHP宿主进程重启都会清空流水号计数器,
// 所以可以采取缓存+数据库结合的模式——如果缓存中有流水号计数器数据则读取并累加计数,如果缓存中没有流水号计数器从数据库中还原计数器。
// 计数器可以每隔一段时间重置一次。既然引入了自增流水号计数器,又会导致文章开头的“德国坦克问题”,
// 所以需要用skip32算法把流水号加密
// (https://github.com/nlenepveu/Skip32)。

// 订单号 = 日期前缀 + 加密流水号

// Skip32 算法加密密钥
const ENCRYPTED_KEY = 'xxxxxxxxxxxx';

// 使用 Wincache 作为流水号计数器缓存
function getOrderSerialNumber() {
    $timestamp = time();
    $datePrefix = date('ymd', $timestamp);
// 如果流水号计数器数据不在缓存中,则尝试从数据库中恢复
    if (false === ($value = wincache_ucache_inc($datePrefix))) {
    wincache_lock($datePrefix);
// 从数据库中获取今日的订单数
    $counter = getNumberOfOrdersTodayFromDatabase($timestamp);
    $value = $counter + 1;
if (!wincache_ucache_add($datePrefix, $value, 60*60*24)) {
    $value = wincache_ucache_inc($datePrefix);
}
    wincache_unlock($datePrefix);
}
    return $datePrefix.str_pad(Skip32::encrypt($datePrefix.ENCRYPTED_KEY, $value), 10, '0', STR_PAD_LEFT);
}

簡単な方法:


1. 現在のタイムスタンプは md5 で暗号化されており、最初の 6 桁はインターセプトされます

echo substr(md5(microtime(true)), 0, 6);

2. データベース bigint を使用してフィールドをインクリメントし、62 に変換して長さを短くします

echo gmp_strval(gmp_init('9876543210', 10), 62);

推奨: 「

PHP ビデオ チュートリアル

以上がPHPで一意で反復しない文字列を生成する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。