方式一:用户id结合业务类型
function createOrdernum($userId,$type){
return date('ymdHis').str_pad($userId,8,0,STR_PAD_LEFT).str_pad(mt_rand(0,999),2,0,STR_PAD_LEFT).str_pad($type,2,0,STR_PAD_LEFT);
}
生成结果为类似2004011555100000000199801的25位订单号,订单号规则为年月日时分秒+用户id+3位随机数+业务类别,这边是预估计用户超过千万设计的,如果没有那么多,可以减少下str_pad($userId,8,0,STR_PAD_LEFT)的位数,降低订单号的长度。
方式二:年月日+业务redis自增+业务类型
function createOrdernum($type){
$redis = Yii::$app->redis;
$count = (int) ($redis->incr($type));
return date('ymdHis').str_pad($count,9,0,STR_PAD_LEFT).str_pad($type,2,0,STR_PAD_LEFT);
}
这样生成的订单号类似20040116021100000000001,长度23位,可以支撑9亿订单量,超过需要调整中间部分长度。如果不考虑美观,中间可以用不补0,长度开始会比较短。我这边用的yii2,其他框架请酌情修改代码。
方式三:年月日+毫秒截取部分+业务
function createOrdernum($type){
return date('ymdhis').substr(microtime(),2,4).str_pad($type,2,0,STR_PAD_LEFT);
}
订单号类似200401042640873001,长度18位。这种方式基本已经满足需求了,无需访问db无随机数参与。但是如果两次请求在相同的十万分之一秒内产生,那么相同订单就产生了。如果担心重复,可以加2位随机数,如下:
function createOrdernum($type){
return date('ymdhis').substr(microtime(),2,4).str_pad(mt_rand(0,99),2,0,STR_PAD_LEFT).str_pad($type,2,0,STR_PAD_LEFT);
}
订单号长度也就变成20位了。