So generieren Sie eine 6-stellige, sich nicht wiederholende Zeichenfolge in PHP
So generieren Sie eine 6-stellige, sich nicht wiederholende Zeichenfolge in PHP
Lassen Sie uns den Zeitstempel studieren. Ich möchte das nicht wiederholen, sondern nur an den Zeitstempel denken.
<code><?php echo substr(md5(microtime(true)), 0, 6); </code>
MD5 der aktuellen Zeit, die ersten 6 Ziffern abfangen. Theoretisch ist es unmöglich,
zu wiederholen
In der Anfangsphase der Erstellung groß angelegter E-Commerce-Websites benötigen Architekten etwa 55 % ihrer Zeit, um Aufträge zu prüfen. Da das Geschäft und die Website-Logik von E-Commerce-Websites hauptsächlich auf Bestellungen (einschließlich Bestellstatus) angewiesen sind. Da es so wichtig ist, analysieren wir, wie PHP qualitativ hochwertige Bestellungen generiert (der Codeausschnitt für PHP zur Generierung von Bestellungen wird unten bereitgestellt). Es ist ein bisschen beängstigend, diesen Artikel zu schreiben, er ist meine persönliche Meinung und dient nur als Referenz.
Verstehen Sie zunächst die allgemeinen Regeln für die Auftragserteilung (einige Auszüge aus dem Internet):
<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>
Die letzte Methode zum Generieren einer Kurz-URL
/**
*Zufallszahlen generieren
*@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>
}
Verwenden Sie die Datenbank bigint, um das Feld zu erhöhen (garantiert eindeutig) und in Hexadezimal umzuwandeln, um die Länge zu verkürzen:
<code><?php echo gmp_strval(gmp_init('9876543210', 10), 62)."\n"; //AmOy42 echo gmp_strval(gmp_init('AmOy42', 62), 10)."\n"; //9876543210</code>
Tatsächlich ist UUID der einzig beste Weg. .