PHP防抖(防重复提交)简单实现

424 阅读2分钟

需求

前端有时表单未做防抖处理,会给后端同时传递重复请求,希望后端代码能屏蔽。

实现:

这里给出本人的非常简单的实现。主要是针对简单需求的。复杂的需求代码肯定没这么简单。 前提:需安装 redis。

代码部分

仅供参考

异常类

 * 防抖异常。这个类留空就行。  
  */  
class AntiRepeatException extends Exception  
{  
}

下面:框架的异常集中处理,自定义 的。这里是 tp 的。larave 类似。

  
use Exception;  
use think\exception\Handle;  
  
class MyException extends Handle  
{  
    public function render(Exception $e)  
    {  
        // 参数验证错误  
        if ($e instanceof AntiRepeatException) {  
  
            return json([ 'code'=>420, 'msg'=>$e->getMessage()  ])  
        }  
        // 其他错误交给系统处理  
        return parent::render($e);  
    }  
  
}  
  

下面是通用的防抖类。


use app\common\exception\AntiRepeatException;
use app\services\Redis;

/**
 * 通用.
 *
 *
 * @author
 */
class AntiRepeat
{

    /**
     * php 防抖通用方法。
     *
     * @param int $user_id 用户id,如设置成0,则表示后端对所有该控制器的请求,无差别限流。
     * @param int $cycle 周期,单位秒,一个周期内只允许一个请求。
     * @throws AntiRepeatException
     */
    public static function handle($user_id = 0, $cycle = 5)
    {
        //域名,注意,这几个参数应该使用各个框架自己提供的,这里是tp示例。
        $host = request()->host();

        //端口
        $port = request()->port();
        // 模块名
        $modules = request()->module();
        // 控制器名称
        $controller = request()->controller();
        // 方法名称
        $method = request()->action();

        $key = 'antiRepeat:' . $host . ':' . $port.":"  .$modules . ':' .
            $controller . ':' . $method . ':' . $user_id;

        $redis = Redis::getInstance();
        if ($redis->get($key) == '1') {
            throw  new AntiRepeatException('请不要提交重复请求');

        } else {
            $redis->setex($key, $cycle, 1);
        }
    }
}//end class

下面是使用示例

{  
    // 假设该控制器的方法需要对登录用户限流 or 防抖。  
    public function index444()  
    {  
        $user_id = Auth::id();// 得到当前登录用户。  
        AntiRepeat::handle($user_id);  
        // 下面做该接口正常的功能实现。  
        // 。。。  
        // 。。。  
        return 'ok';  
    }  
}  

总结

这代码只能应付简单的需求,用于一些用户下订单之类的重要操作。

限流是大概念,防抖可以看成某种简单的限流实现。

即可针对单个登录用户,也可以对所有请求,但实际后者意义不大。

后端独立实现,无需前端配合

CRMEB v4 全开源电商系统,开发者首选

基于ThinkPhp6.0+uniapp 开发的客户管理加电商营销的新零售商城系统。能够真正帮助企业基于微信公众号H5、小程序、wap、pc、APP等,实现会员管理、数据分析,精准营销的电子商务管理系统。可满足企业新零售、批发、分销、预约、O2O、多店等各种业务需求。CRMEB的优势:快速积累客户、会员数据分析、智能转化客户、有效提高销售、会员维护;