【交流】PHP生成唯一邀请码

目录

前言:

1.随机生成,核对user表是否已存在

代码:

解析:

缺点:

2.建表建库,每次从表中随机抽取一条,用完时扩充

表结构

表视图

代码

解析

 缺点

结论:


前言:


目前使用了两种生成唯一邀请码的方法,都觉的不是很完美,有什么好的方法大姐可以交流一下,以下是我的代码逻辑:

1.随机生成,核对user表是否已存在


  • 代码:
function generateInvitationCode($i = 1)
{ 
    $start = 10000;
    $end = 99999;

    // 如果循环了n次,仍然重复,则扩充范围
    // 以避免10000-99999的数字全部都被占用了,在成无限循环
    $multiple = bcdiv($i, 50);
    if($multiple >= 1) {
        $start = $start . str_repeat(0, $multiple); // 拼接$multiple个0
        $end = $end . str_repeat(9, $multiple); // 拼接$multiple个9
    }

    // 生成随机数
    $invitationCode = rand($start, $end); 

    // 检查邀请码是否已经存在于数据库中
    while (checkInvitationCodeExists($invitationCode)) {
        // 如果邀请码已经存在,则重新生成
        $invitationCode = generateInvitationCode($i + 1);
    }

    return $invitationCode;
}
/**
 * 检查不否已存邀请码
*/
function checkInvitationCodeExists($invitationCode)
{
    $user = new User();
    $existingCode = $user->where('invitation_code', $invitationCode)->find();
    if ($existingCode){
        return true;
    }
    return false;
}
  • 解析:
  1. generateInvitationCode() 函数用于生成邀请码。它接受一个可选参数 $i,表示循环次数。如果未提供参数,则默认为 1。

  2. 在 generateInvitationCode() 函数中,我们首先定义了邀请码的范围,即从 10000 到 99999。

  3. 如果循环次数 $i 大于 50,则我们需要扩充邀请码的范围。我们使用 bcdiv() 函数计算 $i 除以 50 的商,并将结果存储在 $multiple 变量中。然后,我们使用 str_repeat() 函数将 $multiple 个 0 和 9 分别拼接到 $start 和 $end 变量中。

  4. 接下来,我们使用 rand() 函数在 $start 和 $end 之间生成一个随机数,并将其存储在 $invitationCode 变量中。

  5. 然后,我们使用 checkInvitationCodeExists() 函数检查邀请码是否已经存在于数据库中。如果邀请码已经存在,则我们递归调用 generateInvitationCode() 函数,并将 $i 参数加 1。

  6. 最后,我们返回生成的邀请码。

  7. checkInvitationCodeExists() 函数用于检查邀请码是否已经存在于数据库中。它接受一个参数 $invitationCode,表示要检查的邀请码。

  8. 在 checkInvitationCodeExists() 函数中,我们首先创建一个新的 User 对象。然后,我们使用 where() 方法查询数据库中是否存在与 $invitationCode 相匹配的邀请码。如果存在,则返回 true,否则返回 false

  • 缺点:

可能会造成多次的user表查询过于频繁

2.建表建库,每次从表中随机抽取一条,用完时扩充


  • 表结构
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for fa_activation_key
-- ----------------------------
DROP TABLE IF EXISTS `fa_activation_key`;
CREATE TABLE `fa_activation_key`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `status` int(2) NOT NULL DEFAULT 0 COMMENT '0未使用1已使用',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `idx`(`id`) USING BTREE,
  INDEX `statusx`(`status`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 110000 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;
  • 表视图

  • 代码
/**
 * 查找一个随机邀请码
 */
function findKey(){
    return Db::name('activation_key')
        ->where('status',0)
        ->orderRaw('rand()')
        ->limit(1)
        ->value('id');
}

/**
 * 生成邀请码
 */
function activationkey(){
    $key = findKey();
    
    if(empty($key)){
        // 如果邀请码用完了,进行库扩建
        $res = createActivationKey();
        if($res){
            // 扩建以后再随机获取一个
            $key = findKey();
        }
    }
    // 把邀请码改为已使用状态
    Db::name('activation_key')->where('id',$key)->update(['status'=>1]);

    return $key;
}

/**
 * 建立邀请码库
 */
function createActivationKey(){
    // 已使用完的邀请码库最大值,从这个值开始往上扩建
    $start = Db::name('activation_key')->order('id desc')->value('id');
    if(empty($start)){
        // 邀请码库为空从10000开始建库
        $start = 10000;
    }else{
        // 邀请码用完从最大值+1开始建库
        $start = bcadd($start,1);
    }
    // 每次扩充99999个邀请码
    $end = bcadd($start,99999);

    $arr = [];
    for ($i=$start; $i<=$end; $i++){
        $arr[] = ['id' => $i];
    }
    // 先把作废的删除掉
    Db::name('activation_key')->where('status', 1)->delete();
    
    // 批量插入邀请码
    Db::name('activation_key')
        ->data($arr)
        ->limit(100)
        ->insertAll($arr);
    return true;
}
  • 解析
  1. findKey() 函数用于查找一个随机邀请码。它使用 Db::name('activation_key') 查询数据库中状态为 0 的邀请码,并按随机顺序排序,使用 limit(1) 限制只返回一个邀请码。最后,使用 value('id') 获取邀请码的 ID。

  2. activationkey() 函数用于生成邀请码。它首先调用 findKey() 函数查找一个随机邀请码。如果 findKey() 返回的邀请码为空,则表示邀请码库已经用完,需要扩建邀请码库。然后调用 createActivationKey() 函数进行扩建。如果扩建成功,再次调用 findKey() 函数查找一个随机邀请码。最后,将邀请码的状态更新为 1,表示已经使用过。

  3. createActivationKey() 函数用于建立邀请码库。它首先获取当前已使用过的邀请码库的最大值,如果没有找到,则从 10000 开始建立邀请码库。然后,每次扩充 99999 个邀请码。接下来,创建一个包含所有邀请码的数组,并先删除状态为 1 的邀请码。最后,批量插入邀请码。

  •  缺点

需要单独的建表建库,每次都需要调用mysql获取,比直接随机生成效率低,但相比第一种在后期会节约一定的时间,减少查询次数

结论:

        方法1,2各有优缺,但都不是很好的解决办法,目前没有想到其他的效率高的办法,有好思路的朋友欢迎指点交流一下

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/236475.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Amazon 亚马逊内推

点击关注公众号&#xff0c;分享 WLB、大厂内推&#xff0c;面经、热点新闻&#xff0c;可内推公司90&#xff0c;累计帮助8000 靠谱的内推君 专注于WLB、大厂精选内推&#xff0c;助力每位粉丝拿到满意的Offer&#xff01; 公司简述 亚马逊公司&#xff08;Amazon&#xff…

基于单片机远程温控检测系统

**单片机设计介绍&#xff0c;基于单片机远程温控检测系统&#xff08;含上位机&#xff09; 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的远程温控检测系统可以用于远程监测和控制温度&#xff0c;实现远程温度监…

UDP报文格式详解

✏️✏️✏️各位看官好&#xff0c;今天给大家分享的是 传输层的另外一个重点协议——UDP。 清风的CSDN博客 &#x1f6e9;️&#x1f6e9;️&#x1f6e9;️希望我的文章能对你有所帮助&#xff0c;有不足的地方还请各位看官多多指教&#xff0c;大家一起学习交流&#xff0…

江苏中服产业党总支一行莅临蓝海创意云参观交流

12月5日上午&#xff0c;江苏中服产业党总支及直播产业“两新”党支部一行莅临蓝海创意云参观交流&#xff0c;蓝海创意云相关领导热情接待&#xff0c;双方就直播业务进行了深度沟通&#xff0c;未来将携手合作共同推动直播产业的创新发展。 在蓝海创意云一楼展厅&#xff0c;…

2024年网络安全竞赛-网站渗透

网站渗透 (一)拓扑图 1.使用渗透机对服务器信息收集,并将服务器中网站服务端口号作为flag提交; 使用nmap工具对靶机进行信息收集 2.使用渗透机对服务器信息收集,将网站的名称作为flag提交; 访问页面即可 3.使用渗透机对服务器渗透,将可渗透页面的名称作为flag提交…

【计算机网络】HTTP响应报文Cookie原理

目录 HTTP响应报文格式 一. 状态行 状态码与状态码描述 二. 响应头 Cookie原理 一. 前因 二. Cookie的状态管理 结束语 HTTP响应报文格式 HTTP响应报文分为四部分 状态行&#xff1a;包含三部分&#xff1a;协议版本&#xff0c;状态码&#xff0c;状态码描述响应头&a…

3-Mybatis

文章目录 项目源码地址Mybatis概述什么是Mybatis&#xff1f;Mybatis导入知识补充数据持久化持久层 第一个Mybatis程序&#xff1a;数据的增删改查查项目名称创建环境编写代码1、目录结构2、核心配置文件&#xff1a;resources/mybatis-config.xml3、mybatis工具类&#xff1a;…

AtCoder ABC周赛2023 11/4 (Sat) E题题解

目录 原题截图&#xff1a; 原题翻译 题目大意&#xff1a; 主要思路&#xff1a; 代码&#xff1a; 原题截图&#xff1a; 原题翻译 题目大意&#xff1a; 给你一个数组&#xff0c;给你一个公式&#xff0c;让你选k个元素&#xff0c;用公式算出最终得分。 主要思路&am…

【论文精读】GAIA: A Benchmark for General AI Assistants

GAIA: A Benchmark for General AI Assistants 前言Abstract1 Introduction2 Related work3 GAIA3.1 A convenient yet challenging benchmark for general AI assistants3.2 Evaluation3.3 Composition of GAIA3.4 Building and extending GAIA 4 LLMs results on GAIA5 Discu…

堆排序算法及实现

1、堆排序定义 堆是一棵顺序存储的完全二叉树。 其中每个结点的关键字都不大于其孩子结点的关键字&#xff0c;这样的堆称为小根堆。其中每个结点的关键字都不小于其孩子结点的关键字&#xff0c;这样的堆称为大根堆。 举例来说&#xff0c;对于n个元素的序列{R0, R1, ... ,…

重温经典struts1之常用标签

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 上一篇&#xff0c;我们学习了struts的基本概念&#xff0c;怎样搭建struts开发环境&#xff0c;从编写formbean&#xff0c;action到jsp页面&#xff0c;以及怎样将他…

用 Python 脚本实现电脑唤醒后自动拍照 截屏并发邮件通知

背景 背景是这样的, 我的家里台式机常年 休眠, 并配置了 Wake On Lan (WOL) 方便远程唤醒并使用。 但是我发现, 偶尔台式机会被其他情况唤醒, 这时候我并不知道, 结果白白运行了好几天, 浪费了很多电。 所以我的需求是这样的&#xff1a; &#x1f914; 电脑唤醒后(可能是开…

spider小案例~https://industry.cfi.cn/BCA0A4127A4128A4141.html

一、获取列表页信息 通过抓包发现列表页信息非正常返回&#xff0c;列表信息如下图&#xff1a; 通过观察发现列表页信息是通过unes函数进行处理的&#xff0c;我们接下来去看下该函数 该函数是对列表页的信息先全局替换"~"为"%u"&#xff0c;然后再通过…

人工智能(pytorch)搭建模型22-基于pytorch搭建SimpleBaseline(人体关键点检测)模型,并详细介绍该网络模型与代码实现

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能(pytorch)搭建模型22-基于pytorch搭建SimpleBaseline(人体关键点检测)模型&#xff0c;并详细介绍该网络模型与代码实现。本文将介绍关于SimpleBaseline模型的原理&#xff0c;以及利用pytorch框架搭建模型…

阿里面试:如何保证RocketMQ消息有序?如何解决RocketMQ消息积压?

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格&#xff0c;遇到很多很重要的面试题&#xff1a; 如何保证RocketMQ消息有序&#xff1f;如何解决RocketMQ消息…

Linux高级系统编程- 消息队列 与 内存共享

消息队列 消息队列是消息的链表&#xff0c;存放在内存中&#xff0c;由内核维护 特点&#xff1a; 1、消息队列中的消息是有类型的。 2、消息队列中的消息是有格式的。 3、消息队列可以实现消息的随机查询。消息不一定要以先进先出的次序读取&#xff0c;编程时 可以按消息的…

Python中的并发编程(3)线程池、锁

concurrent.futures 提供的线程池 concurrent.futures模块提供了线程池和进程池简化了多线程/进程操作。 线程池原理是用一个任务队列让多个线程从中获取任务执行&#xff0c;然后返回结果。 常见的用法是创建线程池&#xff0c;提交任务&#xff0c;等待完成并获取结果&…

Nginx正则表达式

目录 1.nginx常用的正则表达式 2.location location 大致可以分为三类 location 常用的匹配规则 location 优先级 location 示例说明 优先级总结 3.rewrite rewrite功能 rewrite跳转实现 rewrite执行顺序 语法格式 rewrite示例 实例1&#xff1a; 实例2&#xf…

2023年阿里云云栖大会-核心PPT资料下载

一、峰会简介 历经14届的云栖大会&#xff0c;是云计算产业的建设者、推动者、见证者。2023云栖大会以“科技、国际、年轻”为基调&#xff0c;以“计算&#xff0c;为了无法计算的价值”为主题&#xff0c;发挥科技平台汇聚作用&#xff0c;与云计算全产业链上下游的先锋代表…

网线市场现状与发展趋势预测

随着物联网、5G、云计算等技术的迅速发展&#xff0c;全球对于高速、稳定的网络需求急剧增长&#xff0c;这进一步推动了网线市场的发展。各种网络应用场景&#xff0c;从家庭到企业、数据中心到智能城市&#xff0c;都需要大量的高质量网线来支持数据传输和通信需求。本文将对…