PHP的订单号生成算法算是语言本身的硬伤吧,相信很少的大型互联网公司会用PHP去生成订单号了,但是如果你身处一个没有各方资源的情况下还是仔细想想怎么做吧,
PHP相比JAVA而言是以进程的方式运行的,进程结束资源回收,所有不会跟java一样会保存static等全局的东西(不考虑分布式),所以如果要实现一个递增的订单号必须要依赖第三方的东西比如memcache,redis,mysql等然后每次生成都要依赖这些上游去递增。
公司之前做的系统有这方面的需求而且公司目前只有PHP这个,刚刚开始考虑的snowflake算法,但是后来发现这个生成的订单号太长了,并不是每个业务都适合这个,比如你生成一个40几位的订单号,然后客户打电话过来咨询,报了这么一长串,客服会不会心态爆炸。。 哈哈 无法想象,因此订单号最好短一点,又容易记一点。
废话不多说,直接上代码,很简单,做映射。顺便说一句,PHP不依赖第三方的东西,订单号始终有可能重复,只能想办法降低这个概率,让它几乎不可能发生
/**
* 生成15位的订单号
* @return string 订单号
*/
public function createOrderNm()
{
$year_code = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z');
$date_code = array('0',
'1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'T', 'U', 'V', 'W', 'X', 'Y');
//一共15位订单号,同一秒内重复概率1/10000000,26年一次的循环\
$order_sn = $year_code[(intval(date('Y')) - 2010) % 26] . //年 1位
strtoupper(dechex(date('m'))) . //月(16进制) 1位
$date_code[intval(date('d'))] . //日 1位
substr(time(), -5) . substr(microtime(), 2, 5) . //秒 5位 // 微秒 5位
sprintf('%02d', rand(0, 99)); // 随机数 2位
return $order_sn;
}