LNMP集合PHP经验分享

唯一随机码解读----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();
    }
}
上一篇下一篇

猜你喜欢

热点阅读