当前位置:  编程技术>php

php生成订单号的解决方案

    来源: 互联网  发布时间:2014-10-04

    本文导语:  在php中关于生成订单号的解决方案,值得借鉴。 前期开发的一个交易系统,原本使用的是uniqid()函数生成的。 uniqid()是根据系统时间经过一定算法得到的一个结果,关于uniqid()的详情手册上很清楚。 当时的生产方式是: $order_...

在php中关于生成订单号的解决方案,值得借鉴。

前期开发的一个交易系统,原本使用的是uniqid()函数生成的。
uniqid()是根据系统时间经过一定算法得到的一个结果,关于uniqid()的详情手册上很清楚。
当时的生产方式是:
$order_sn = str_replace('.', '', uniqid('', true));

这种方式理论上说会重复,但是在实际应用中我相信这种重复可以认为是不可能事件。但是,如果这件事情到此就结束的话我也就不会再写这篇文章。这几天做支付接入,国内某大型网络支付机构只支持传递最多16位的订单号,无奈我只得调整订单号的生产规则。
其实关于生成订单号的方式非常多,大致有以下几个参数被用到:
1、自增字段,2、系统时间,3、随机数,4、流水号。

一、数据库自增字段
二、简单的使用系统时间
三、系统时间加随机数
四、系统时间加流水号

先说说mysql数据库自增字段,这种方式是最简单有效的方式,但同时也存在很大的弊端:
1、以mysql为例的int类型最多存储10位的数字,如果使用bigint则在使用php的mysql_insert_id()取上次插入id时会出现错误,当然这个错误是可以采用某些方法避免的。

2、很多时候业务逻辑需要在数据未插入系统之前就获得订单号以进行一系列的处理,这样就容易出错。
比如当并发较高的时候系统获取到下一次插入的id应该是10000,可是当真正insert的时候发现10000已经被其他插入行使用。

3、很容易透露出系统的销量,从商业层面说这种方式不太合适。

4、表现不够直观,不能通过订单号简表达订单信息

简单的使用系统时间也可以有多种方式比如直接使用time()生成10位数字,这种方式基本避免了数据库自增字段的大部分弊端,但同时也产生的一些新的问题,比如:并发量稍高(峰值每秒一次以上,相信这是个很小的值)就会产生相同订单号,而这是业务逻辑所不允许的。为了解决重复订单问题而使用随机数或者流水号。

先说随机数,这东西就跟看上去的字面意思一样,总显得不那么可靠,我认为尽量不使用它参与唯一标识。
再说流水号,既然叫流水号,它的性质其实和自增字段一样,不同的是或许每天或者每月流水号又会重新计数。总得有个地方来保存下一个(或者当前使用过的最大)流水号的值,如果存在文件中那就需要考虑这个文件的读写锁的问题,就这个问题估计足够写书了,在此不予讨论。如果以自增方式存在db中,那么我们在程序生成订单号之前需要多访问(至少)一次db,这也就降低了程序性能,要知道数据库访问对程序的性能影响是非常明显的。

相关链接:php 自动生成订单编号二种方法

解决思路(php),当然同时别忘了大前提是:限制长度16位
第一步:

$order_sn = date('ymdhis').substr(microtime(),2,4);

其实这种方式基本已经满足需求了,无需访问db无随机数参与。但是如果两次请求在相同的十万分之一秒内产生,那么相同订单就产生了,看能否有办法继续提高。

date(‘his’)所表达的结果其实就是000000到235959,而且其中很多数字不会被用到比如126998。一天86400秒,如果从一天的0:0:0算起直到23:59:59使用00000-86400就可以完全表示,这样下来我们就完全可以把date(‘his’)换成五位数字。既然time()函数就是按秒计数,那咱就取time()结果的后五位,同一天之内后五位不会重复出现,比如今天0:0:0后五位是98765,那么到今天23:59:59后五位就应该是98765+86400去掉最高位,相信这个应该是很好理解的。

这就产生了第二步的结果:
$order_sn = date('ymd').substr(time(),-5).substr(microtime(),2,5);

这样一来也导致无法直观的表达出订单生成的时分秒,但我认为(或者说从业务角度理解)这个属于可接受范围。同时这样处理出现重复订单的概率就降低到了第一步的1/10,我以为这应该不算一个小数字。还不满意?ok,那继续!

想要继续降低重复可能性那就继续提高时间精度,但是我们的长度限制只有16位,看来只有减少部分不长变动的字符。

date(‘ymd’)产生6位字符,而前两位在一年之内都不会变化,第三到第四位也就是01-12。
前两位我们可以使用a-z的字母来表示,系统开始运行的那一年用a,第二年用b,第三年用c……类推,我相信我写的这程序运行不了10年。第三第四位完全可以使用一位16进制数表示,这样咱就又节约了两位字符,这就可以在末尾加上00-99的随机数。

现在看第三步的结果
 

代码示例:
$year_code = array('a','b','c','d','e','f','g','h','i','j');
$order_sn = $year_code[intval(date('y'))-2010].
strtoupper(dechex(date('m'))).date('d').
substr(time(),-5).substr(microtime(),2,5).sprintf('d',rand(0,99));

( www.)理论上说出现重复订单号的概率又降到了第二步的1/100。
做个简单测试,写个php文件,连续10次echo出这三步结果得到的$order_sn,中间无任何多余程序。
第一种方案基本得到10个相同的结果。
第二种方案基本得到10个不同的结果,主要是后两位不同,一般末位差一。
第三种方案得到10个不同结果末四位不同
当然这个测试不具备多少说服力

优点:
1、不用操作数据库,性能较高。
2、较为直观,不难看出订单产生的大致时间
3、订单号重复的概率极小,只有程序在百万分之一秒内同时处理一个以上的生成订单号请求,而且同时生成的0-99的随机数也一样才会出现重复的订单号。


    
 
 

您可能感兴趣的文章:

  • php生成订单号的类 php订单号生成代码
  • php订单号生成方案探讨
  • php生成不重复的随机订单号
  • php 生成订单号二种方法
  • php生成唯一订单号实例代码
  • php中session_id()函数详细介绍,会话id生成过程及session id长度
  • PHP源码自动生成插件 PHP Source Plugin
  • php微博短网址算法 php生成短网址的实现代码
  • PHP 对象生成器 POG
  • php生成短网址 仿微博短网址生成代码
  • php生成数组与php全组合算法
  • 生成假数据的PHP库 Faker
  • php生成唯一标识符的代码
  • PHP代码生成器 PHPGEN
  • php guid生成函数 php生成唯一标识符
  • php生成excel中的列序号
  • PHP验证码生成脚本 Securimage
  • php生成数组的使用示例 php全组合算法
  • PHP生成静态文件简单示例
  • php生成指定位数(长度)的随机字符串
  • PHP生成PDF的类 FPDF
  • php生成短网址示例代码
  • PHP静态网站生成工具 Phrozn
  • PHP生成自定义长度随机字符串的函数分享
  • php动态生成函数示例
  • php动态生成函数的例子
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • php 自动生成订单编号二种方法
  • 修改配置真正解决php文件上传大小限制问题(nginx+php)
  • IIS7配置PHP图解(IIS7+PHP_5.2.17/PHP_5.3.5)
  • PHP 5.4.19 和 PHP 5.5.3 发布及下载地址
  • php输入流php://input使用示例(php发送图片流到服务器)
  • 修改配置真正解决php文件上传大小限制问题(apache+php)
  • PHP转换器 HipHop for PHP
  • PHP去除html标签,php标记及css样式代码参考
  • PHP 框架 Pop php
  • PHP 'ext/soap/php_xml.c'不完整修复存在多个任意文件泄露漏洞
  • PHP的JavaScript框架 PHP.JS
  • php通过socket_bind()设置IP地址代码示例
  • php服务器探针显示php服务器信息
  • php安装完成后如何添加mysql扩展
  • PHP缓存加速器 Alternative PHP Cache (APC)
  • PHP的substr() 函数用法
  • PHP源文件加密工具 PHP Screw
  • PHP介绍及学习网站推荐
  • PHP自动化测试 PHP-QAT
  • php中操作memcache的类及成员列表及php下如何连接memched服务器
  • PHP 的 HTTP 客户端库 PHP Buzz
  • php中内置的mysql数据库连接驱动mysqlnd简介及mysqlnd的配置安装方式
  • PHP 调试工具 PHP_Dyn


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3