> 백엔드 개발 > PHP 튜토리얼 > PHP에서 반복되지 않는 6자리 문자열을 생성하는 방법

PHP에서 반복되지 않는 6자리 문자열을 생성하는 방법

WBOY
풀어 주다: 2023-03-02 10:28:01
원래의
2011명이 탐색했습니다.

PHP에서 반복되지 않는 6자리 문자열을 생성하는 방법

답글 내용:

PHP에서 반복되지 않는 6자리 문자열을 생성하는 방법

타임스탬프에 대해 공부해보자. 반복하고 싶지 않고 타임스탬프만 생각해보자.

<code><?php

echo substr(md5(microtime(true)), 0, 6);
</code>
로그인 후 복사

현재 시간의 MD5, 처음 6자리를 가로채세요. 이론적으로 반복은 불가능합니다

대규모 전자상거래 웹사이트 구축 초기 단계에서 건축가는 주문을 고려하는 데 약 55%의 시간이 필요합니다. 전자상거래 웹사이트 비즈니스와 웹사이트 로직은 주로 주문(주문 상태 포함)에 의존하여 운영되기 때문입니다. 이는 매우 중요하므로 PHP가 고품질 주문을 생성하는 방법을 분석해 보겠습니다(PHP에서 주문을 생성하는 코드 조각은 아래에 제공됩니다). 이 글을 쓰기가 좀 두렵습니다. 모두 제 개인적인 생각이고 참고용입니다.

먼저 주문에 대한 일반 규칙을 이해하세요(인터넷에서 일부 발췌):

<code>1、不重复。
2、安全性。
    2.1 不建议使用啥敏感的数据作为订单生成规则(例如:用户UID,订单自增ORDER_ID等),以为会暴露网站一些敏感信息

3、不能使用大规模随机码。
    why? 
    3.1 首先问你"编程语言中的随机能做到真随机吗?",我可以不自信的告诉你至少PHP做不到,所以可能导致第一个"不重复"原则发生
    3.2 如果你的订单数量到达了1000w次,你每次生成订单编码时就得对比1000w条历史数据,一般在500w的时候,你得花时间在数据库优化上(简单处理:采用分区,建立索引,然而实际性要求高,可能需要在主数据库下操作,可想你有多痛,当然对于数据库实时读写还有其他的优化办法,在此不作介绍)。
4、防止并发。
5、控制位数。
    why?
    5.1 便于查询检索
    5.2 位数控制到 10~20位即可,当然网上将的是10~15缘由是利于输入,对于输入太长做好用户体验就好(新增复制订单按钮)
    
6、尽量具有业务意义(不是强制的,根据公司业务来)
    6.1 当你业务比较庞大时候,或者后期有大规模的扩充时,建议考虑下订单的生成意义,根据公司的业务做调整。举个最简单的例子:"一个卖化妆品的商城,你需要根据订单来源来(pc/移动)来生成报表,这时候可能需要"
    
7.解决办法
    
    7.1 类似生成 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);
    }</code>
로그인 후 복사

단축 URL 생성에 사용된 마지막 방법

/**
*난수 생성
*@param
*/
function randStr($m= 5) {

<code>$new_str= '';
$str= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyz0123456789';
for($i= 1; $i<= $m; ++$i) {
    $new_str.=$str[mt_rand(0, 61)];
}
return $new_str;</code>
로그인 후 복사

}

데이터베이스 bigint를 사용하여 필드를 증가시키고(고유함 보장) 길이를 줄이기 위해 16진수로 변환합니다.

<code><?php
echo gmp_strval(gmp_init('9876543210', 10), 62)."\n"; //AmOy42
echo gmp_strval(gmp_init('AmOy42',     62), 10)."\n"; //9876543210</code>
로그인 후 복사

사실 가장 좋은 방법은 UUID뿐입니다. .

관련 라벨:
php
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿