tp5.1处理频繁发送验证码,检查手机号和ip

本文介绍了一个PHP实现的验证码发送限制系统,针对同一个手机号一天内最多发送6次验证码,每次发送后需等待特定时间间隔。系统通过读写文件记录每日发送次数,确保在规定时间内限制发送。当超过次数时,会提示用户明日再试。
摘要由CSDN通过智能技术生成

1、本文借鉴的是[https://www.cnblogs.com/blogforly/p/5841811.html]
(https://www.cnblogs.com/blogforly/p/5841811.html)
2、监听一个手机号一天只能发送6次验证码。
时间间隔为:第一次发送验证码后,间隔1分钟之后可以重发。第二次发送验证码后,间隔5分钟之后可以重发。第三次发送验证码后,间隔10分钟之后可以重发。第四次发送验证后,间隔20分钟后可以重发。第五次发送验证码后,间隔30分钟后可以重发。第六次发送验证后,间隔24小时后可以重发。
3、思路:每一天,在项目的指定路径下,写一个文件,该文件记录所有当天发送了验证码的手机号。在每一次用户发送验证码时,从该文件取出用户手机号在该文件夹下,存在几次记录,做相应的处理。
代码如下:

<?php


namespace app\home\model\v2;


use think\Exception;

/**
 * 记录当前用户,当天请求了多少次验证码接口
 * Class ReMod
 * @package app\home\controller\v2
 */
class ReMod
{
//定义全局变量,用于设置记录文件的路径
    protected $Root = null;

    public function __construct()
    {
        $this->Root = "data/msg_logs/";//自己定义的文件存放位置 /public/data/msg_logs 路径
    }

    //检测Tel在文件中出现的次数
    public function checkTel($data)
    {
        $fileName = "Tel_" . date("Ymd", time()) . ".dat";
        $filePath = ($this->Root) . $fileName;
        $c_sum = 0;
        if (file_exists($filePath)) {
            $arr = file_get_contents($filePath);
            $row = explode("|", $arr);
            //如果当前文件中,有当前手机号
            if(in_array($data,$row)){
                //计算每一个value有多少个,并且将value当键,将多少个当值,组成一个新的数组
                $countArr = array_count_values($row);
                //查询当前手机号的对应的值
                $c_sum = $countArr[$data];
                if ($c_sum < 6) {
                    $this->wirteFile($filePath, $data . "|");
                }
                return $c_sum;
            }else{
                $this->wirteFile($filePath, $data . "|");
                return $c_sum;
            }
        } else {
            $this->wirteFile($filePath, $data . "|");
            return $c_sum;
        }
    }


    /**
     * 105 * 将数据写入本地文件
     * 106 * @param string $filePath 要写入文件的路径
     * 107 * @param string $data 写入的数据
     * 108 */
    public function wirteFile($filePath, $data)
    {
        try {
            if (!is_dir($this->Root)) {//判断文件所在目录是否存在,不存在就创建
                mkdir($this->Root, 0777, true);
            }
            if ($filePath == "") {//此处是不发送验证码时,记录日志创建的文件
                $filePath = ($this->Root) . "N" . date("Ymd", time()) . ".dat";
            }
            //写入文件操作
            $fp = fopen($filePath, "a+");//得到指针
            fwrite($fp, $data);//写
            fclose($fp);//关闭
        } catch (Exception $e) {
            print $e->getMessage();
        }
    }

}

在发送验证码接口,添加一个方法

 public function actionSendSms(Request $request)
    {
        (new MobileVaildate())->apiCheck();

        $param = $request->only(['mobile', 'time', 'sign']);
        //验证验签
        Safe::vaildateSign($param);
        //电话
        $tel = $param['mobile'];
        //判断当前用户的手机号今日发送了几次请求
        $tel_num = (new ReMod)->checkTel($tel);

        $JUid = Cache::get('JU_ID_CODE');

        //从redis中获取下一次最早发送验证码的时间
        $redis = new RedisPro();
        $time = $redis->get($param['mobile'] . 'login_code' . 'time');

        //当缓存中不存在这个时间点,并且当前小于这个时间点,则给出提示
        if ($time !== false && time() < $time) {
            return reply(10500, '请于' . date('Y-m-d H:i:s', $time) . '之后发送!');
        }

        //判断手机号 如果是当天第 1 次发送 则 1 分钟之后发送
        if ($tel_num == 0) {
            // dump('今天第一次进来');
            (new Send())->sendMessage($param['mobile'], $JUid, 'login_code', 1 * 60);
            //    如果是当天第 2 次发送 则 5 分钟之后发送
        } else if ($tel_num == 1) {
            // dump('今天第2次进来');
            (new Send())->sendMessage($param['mobile'], $JUid, 'login_code', 5 * 60);
            // 如果是当天第 3 次发送 则 10 分钟之后发送
        } else if ($tel_num == 2) {
            // dump('今天第3次进来');
            (new Send())->sendMessage($param['mobile'], $JUid, 'login_code', 10 * 60);
            //    如果是当天第 4 次发送 则 20 分钟之后发送
        } else if ($tel_num == 3) {
            // dump('今天第4次进来');
            (new Send())->sendMessage($param['mobile'], $JUid, 'login_code', 20 * 60);
            // 如果是当天第 5 次发送 则 30 分钟之后发送
        } else if ($tel_num == 4) {
            // dump('今天第5次进来');
            (new Send())->sendMessage($param['mobile'], $JUid, 'login_code', 30 * 60);
            // 如果是当天第 6 次发送 则 24小时之后发送
        } else if ($tel_num == 5) {
            // dump('今天第6次进来');
            (new Send())->sendMessage($param['mobile'], $JUid, 'login_code', 24 * 60 * 60);
        } else if ($tel_num > 5) {
            // dump('今天第7次或以上进来');
            //当不发送验证码时,将数据存入文件,用于方便查询
            // $data = $tel . "|";
            // if ($tel_num > 5) {
            //     $data = $data . "B@";
            // }
            // (new ReMod)->wirteFile("", $data);
            return reply(10501, '您今日获取短信验证码的次数已达到6次,请明日再试!');//给用户返回信息
        }
        return reply(10200, '短信验证码发送成功');
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值