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

news2024/12/17 17:52:27

目录

前言:

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各有优缺,但都不是很好的解决办法,目前没有想到其他的效率高的办法,有好思路的朋友欢迎指点交流一下

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【rabbitMQ】rabbitMQ的下载,安装与配置

目录 1. 下载Erland 安装步骤&#xff1a; 配置环境变量&#xff1a; 校验环境变量配置是否成功 2.下载MQ 安装步骤&#xff1a; 添加可视化插件 &#xff1a; 启动&#xff1a; 拒绝访问 1. 下载Erland 因为rabbitMQ是基于Erland,所以在安装rabbitMQ之前需要安装Erla…

距离度量(各距离含义)

欧氏距离 在n维空间中两点的真实距离&#xff0c;向量的自然长度 由于欧几里得几何学的关系称为欧氏距离 二维空间两点计算公式&#xff1a; d ( x 1 − x 2 ) 2 ( y 1 − y 2 ) 2 d \sqrt{(x_1 - x_2)^2 (y_1 - y_2)^2} d(x1​−x2​)2(y1​−y2​)2 ​ 三维空间两点计算…

7.MySQL 存储过程

目录 概述 概念&#xff1a; 特性&#xff1a; 变量 局部变量 定义方法&#xff1a; 语法1: 语法2: 用户变量 语法&#xff1a; 系统变量 全局变量 会话变量 参数传递 in out inout 流程控制 分支语句 if case 循环语句 循环控制: while while while…

Java面试遇到的一些常见题

目录 1. Java语言有几种基本类型&#xff0c;分别是什么&#xff1f; 整数类型&#xff08;Integer Types&#xff09;&#xff1a; 浮点类型&#xff08;Floating-Point Types&#xff09;&#xff1a; 字符类型&#xff08;Character Type&#xff09;&#xff1a; 布尔类…

基于Springboot的校园失物招领系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的校园失物招领系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

【智能家居】七、人脸识别 翔云平台编程使用(编译openSSL支持libcurl的https访问、安装SSL依赖库openSSL)

一、翔云 人工智能开放平台 API文档开发示例下载 二、编译openSSL支持libcurl的https访问 安装SSL依赖库openSSL(使用工具wget)libcurl库重新配置&#xff0c;编译&#xff0c;安装运行&#xff08;运行需添加动态库为环境变量&#xff09; 三、编程实现人脸识别 四、Base6…

react中使用react-konva实现画板框选内容

文章目录 一、前言1.1、API文档1.2、Github仓库 二、图形2.1、拖拽draggable2.2、图片Image2.3、变形Transformer 三、实现3.1、依赖3.2、源码3.2.1、KonvaContainer组件3.2.2、use-key-press文件 3.3、效果图 四、最后 一、前言 本文用到的react-konva是基于react封装的图形绘…

【rabbitMQ】rabbitMQ控制台模拟收发消息

目录 1.新建队列 2.交换机绑定队列 3.查看消息是否到达队列 总结&#xff1a; 1.新建队列 2.交换机绑定队列 点击amq.fonout 3.查看消息是否到达队列 总结&#xff1a; 生产者&#xff08;publisher&#xff09;发送消息&#xff0c;先到达交换机&#xff0c;再到队列&…

深度学习之全面了解预训练模型

在本专栏中&#xff0c;我们将讨论预训练模型。有很多模型可供选择&#xff0c;因此也有很多考虑事项。 这次的专栏与以往稍有不同。我要回答的问题全部源于 MathWorks 社区论坛&#xff08;ww2.mathworks.cn/matlabcentral/&#xff09;的问题。我会首先总结 MATLAB Answers …

计算机视觉-05-目标检测:LeNet的PyTorch复现(MNIST手写数据集篇)(包含数据和代码)

文章目录 0. 数据下载1. 背景描述2. 预测目的3. 数据总览4. 数据预处理4.1 下载并加载数据&#xff0c;并做出一定的预先处理4.2 搭建 LeNet-5 神经网络结构&#xff0c;并定义前向传播的过程4.3 将定义好的网络结构搭载到 GPU/CPU&#xff0c;并定义优化器4.4 定义训练过程4.5…

机器学习算法(9)——集成技术(Bagging——随机森林分类器和回归)

一、说明 在这篇文章&#xff0c;我将向您解释集成技术和著名的集成技术之一&#xff0c;它属于装袋技术&#xff0c;称为随机森林分类器和回归。 集成技术是机器学习技术&#xff0c;它结合多个基本模块和模型来创建最佳预测模型。为了更好地理解这个定义&#xff0c;我们需要…

C语言进阶之路之结构体、枚举关卡篇

目录 一、学习目标 二、组合数据类型-结构体 结构体基本概念 结构体的声明&#xff1a; 小怪实战 结构体初始化 指定成员初始化的好处&#xff1a; 结构体成员引用 结构体指针与数组 关卡BOOS 三、结构体的尺寸 CPU字长 地址对齐 结构体的M值 可移植性 四、联合体…

ssm的健身房预约系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; ssm的健身房预约系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring Spring…

极智一周 | AI 算力国产化、通义开源、Gemini、鸿蒙、蔚来 And so on

欢迎关注我的公众号 [极智视界]&#xff0c;获取我的更多技术分享 大家好&#xff0c;我是极智视界&#xff0c;带来本周的 [极智一周]&#xff0c;关键词&#xff1a;AI 算力国产化、通义开源、Gemini、鸿蒙、蔚来 And so on。 邀您加入我的知识星球「极智视界」&#xff0c;…

c-语言->数据在内存的存储

系列文章目录 文章目录 系列文章目录前言 前言 目的&#xff1a;学习整数在内存的储存&#xff0c;什么是大小端&#xff0c;浮点数的储存。 1. 整数在内存中的存储 在讲解操作符的时候&#xff0c;我们就讲过了下⾯的内容&#xff1a; 整数的2进制表⽰⽅法有三种&#xff0…

带有 RaspiCam 的 Raspberry Pi 监控和延时摄影摄像机

一、说明 一段时间以来&#xff0c;我一直想构建一个运动激活且具有延时功能的树莓派相机&#xff0c;但从未真正找到我喜欢的案例。我在thingiverse上找到了这个适合树莓派和相机的好案例。它是为特定的鱼眼相机设计的&#xff0c;但从模型来看&#xff0c;我拥有的廉价中国鱼…

STM32F1之CAN报文传输

目录 报文传输 1. 帧类型 1.1 数据帧 1.1.1 帧起始 1.1.2 仲裁场 1.1.3 控制场 1.1.4 数据场 1.1.5 CRC 场 1.1.6 应答场 1.1.7 帧结尾 1.2 远程帧 1.3 错误帧 1.4 过载帧 1.5 帧间空间&#xff08;INTERFRAME SPACING&#xff09; 2. 发送器/接收器的…

【动态规划】【广度优先】LeetCode2258:逃离火灾

作者推荐 本文涉及的基础知识点 二分查找算法合集 动态规划 二分查找 题目 给你一个下标从 0 开始大小为 m x n 的二维整数数组 grid &#xff0c;它表示一个网格图。每个格子为下面 3 个值之一&#xff1a; 0 表示草地。 1 表示着火的格子。 2 表示一座墙&#xff0c;你跟…

【C语言】内联函数

一、内联函数 在C语言中&#xff0c;内联函数&#xff08;Inline function&#xff09;是一种代码优化技术&#xff0c;它的目的是减少函数调用的开销。内联函数通知编译器在每个函数调用的位置插入函数的实际代码&#xff0c;而不是进行传统的函数调用。这避免了调用函数时的…

球上进攻^^

欢迎来到程序小院 球上进攻 玩法&#xff1a;点击鼠标走动躲避滚动的球球&#xff0c;球球碰到即为游戏结束&#xff0c;看看你能坚持多久&#xff0c;快去玩吧^^。开始游戏https://www.ormcc.com/play/gameStart/214 html <div id"game" class"game" …