唯一随机码解读----laravel5
2017-10-09 本文已影响41人
hyperbolaa
1.需求
用户购买商品, 给用户提供一个核销码, 用户凭核销码到店铺核销使用
核销码要求类似美团核销码,16位纯数字
2.问题
如何避免核销码重复
3.思考
方式1: 存数据表的递增属性,
缺点: 若用户掌握规律, 存在刷码的情况,不可取
方式2: 在数据表中存放随机核销码, 每次在表中查询唯一性
缺点: 若并发高, 每次查询数据库存在性能差,不可取
方式3: 使用uniqid() 函数基于以微秒计的当前时间,生成一个唯一的 ID。
缺点: 大并发的情况下存在重复核销码的情况
方式4: 基于方式3的方式生成10000个核销码放入缓存中, 每个核销码标记个使用状态,使用的核销码状态标记为已使用,更新缓存; 用完之后重新调用方式3的方式重新生成10000个核销码放入缓存中,如此递归......
4.实践
function create_code_sn(){
$key = date('Ymd');
if(Cache::has($key)){
$codes = Cache::get($key);
}else{
$codes = [];
for ($i=0;$i<10000;$i++){
$codes[] = [
'code' => date('Ymd') . substr(implode(null, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), -8),
'used' => false
];
}
//去重复
$codes = collect($codes)->unique('code')->values()->all();
}
//取出当前的数据
foreach ($codes as $k=>$code){
if(!$code['used']){
$codes[$k]['used'] = true;
$codeSn = $code['code'];
break;
}
}
//缓存数据,缓存一天时间
Cache::put($key,$codes,1440);
if(isset($codeSn)){
return $codeSn;
}else{
Cache::flush();
return create_code_sn();
}
}