PHP 实现防抖功能(防重复请求)

原理

  1. 使用Redis做接口访问锁,访问前加锁,访问结束后解锁。
  2. 使用 域名+antiRepeat+模块+控制器+方法名称+用户ID”作为唯一key值,用户ID默认自动获取,也可以由参数传入

基础代码

Larave或Lumen框架

/*** 通用接口防抖函数*/
function antiRepeat($unique_id = false)
{if (!$unique_id && !auth()->id()) {fail('该方法使用“域名+模块+控制器+方法名称+用户ID”作为唯一key值,无法使用auth()->id()的接口请传入unique_id参数代替 用户ID');}// 获取请求的模块、控制器、方法名称list($class, $method) = explode('@', request()->route()[1]['uses']);// 模块名$modules = str_replace('\\','.',str_replace('App\\Http\\Controllers\\','',trim(implode('\\', array_slice(explode('\\', $class), 0, -1)),'\\')));// 控制器名称$controller = str_replace('Controller','',substr(strrchr($class, '\\'), 1));// 传入$unique_id则优先使用$unique_idif ($unique_id) {$key = $_SERVER['HTTP_HOST'] . '-antiRepeat-' . $modules . '.' . $controller . '.' . $method . '.' . $unique_id;} else {$key = $_SERVER['HTTP_HOST'] . '-antiRepeat-' . $modules . '.' . $controller . '.' . $method . '.' . auth()->id();}// 访问进行中if (Redis::get($key) == 1) {fail('请勿重复操作');} else {Redis::set($key, 1);register_shutdown_function(function () use ($key) {// Redis::set($key, 0);Redis::del($key);});}
}/*** 通用接口防抖函数*/
function antiRepeatTime($unique_id = false, $seconds = 8)
{if (!$unique_id && !auth()->id()) {fail('该方法使用“域名+模块+控制器+方法名称+用户ID”作为唯一key值,无法使用auth()->id()的接口请传入unique_id参数代替 用户ID');}// 获取请求的模块、控制器、方法名称list($class, $method) = explode('@', request()->route()[1]['uses']);// 模块名$modules = str_replace('\\','.',str_replace('App\\Http\\Controllers\\','',trim(implode('\\', array_slice(explode('\\', $class), 0, -1)),'\\')));// 控制器名称$controller = str_replace('Controller','',substr(strrchr($class, '\\'), 1));// 传入$unique_id则优先使用$unique_idif ($unique_id) {$key = $_SERVER['HTTP_HOST'] . '-antiRepeatTime-' . $modules . '.' . $controller . '.' . $method . '.' . $unique_id;} else {$key = $_SERVER['HTTP_HOST'] . '-antiRepeatTime-' . $modules . '.' . $controller . '.' . $method . '.' . auth()->id();}// 访问进行中if (Redis::get($key) == 1) {fail('请求过于频繁');} else {Redis::setex($key, $seconds, 1);}
}

ThinkPHP框架

/*** 通用接口防抖函数*/
function antiRepeat($unique_id = false)
{$auth = Auth::instance();if (!$unique_id && !$auth->id) {fail('该方法使用“域名+模块+控制器+方法名称+用户ID”作为唯一key值,无法使用auth()->id()的接口请传入unique_id参数代替 用户ID');}// 这里可以换成其他缓存机制$redis = Cache::store('redis');// 模块名$modules = request()->module();// 控制器名称$controller = request()->controller();// 方法名称$method = request()->action();// 传入$unique_id则优先使用$unique_idif ($unique_id) {$key = $_SERVER['HTTP_HOST'] . '-antiRepeat-' . $modules . '.' . $controller . '.' . $method . '.' . $unique_id;} else {$key = $_SERVER['HTTP_HOST'] . '-antiRepeat-' . $modules . '.' . $controller . '.' . $method . '.' . $auth->id;}// 访问进行中if ($redis->get($key) == 1) {fail('请勿重复操作');} else {$redis->set($key, 1);register_shutdown_function(function () use ($key, $redis) {$redis->set($key, 0);});}
}

使用示例

  1. 如果是能使用auth()->id()获得用户ID的接口
antiRepeat();...业务代码
  1. 如果是不能使用auth()->id()获得用户ID的接口
$user_id = 1;// 自行设置用户ID
antiRepeat($user_id);...业务代码

by 同事 - kaivin99

PHP 实现防抖功能(防重复请求)相关推荐

  1. spring 注解重复(防重复请求)

    1.配置拦截器 spring-mvc.xml <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/ ...

  2. 防止跨站请求伪造(CSRF)攻击 和 防重复提交 的方法的实现

    CSRF的概念可以参考:http://netsecurity.51cto.com/art/200812/102951.htm 本文介绍的是基于spring拦截器的Spring MVC实现 首先配置拦截 ...

  3. 利用redis实现分布式请求防重复提交

    2019独角兽企业重金招聘Python工程师标准>>> 1.自定义注解类Token @Target(ElementType.METHOD) @Retention(RetentionP ...

  4. springboot 主键重复导致数据重复_Springboot实现防重复提交和防重复点击(附源码)...

    背景# 同一条数据被用户点击了多次,导致数据冗余,需要防止弱网络等环境下的重复点击 目标# 通过在指定的接口处添加注解,实现根据指定的接口参数来防重复点击 说明# 这里的重复点击是指在指定的时间段内多 ...

  5. 分布式架构:并发重复请求和幂等场景技术实现总结

    分布式架构:并发重复请求和幂等场景技术实现总结 原文:分布式架构:并发重复请求和幂等场景技术实现总结 概念 重复请求是指一个请求因为某些原因被多次提交,场景简述如下: 1)用户快速多次点击按钮 2)N ...

  6. 防重复请求处理的实践与总结

    #防重复处理总结 ##背景 在业务开发中,我们常会面对防止重复请求的问题.当服务端对于请求的响应涉及数据的修改,或状态的变更时,可能会造成极大的危害.重复请求的后果在交易系统.售后维权,以及支付系统中 ...

  7. redis+aop防重复提交

    文章目录 1.防重复提交注解 2.redis分布式锁 3.防止重复提交Aop 之前有记录一篇用redis+拦截器防重复提交的内容: redis+拦截器防重复提交 1.防重复提交注解 @Target(E ...

  8. 由防重复点击引发的幂等性问题思考

    HTTP/1.1中对幂等性的定义是:一次和多次请求某一个资源对于资源本身应该具有同样的结果(网络超时等问题除外).也就是说,用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而 ...

  9. java mysql防重复提交_防止数据重复提交的6种方法(超简单)!

    有位朋友,某天突然问磊哥:在 Java 中,防止重复提交最简单的方案是什么? 这句话中包含了两个关键信息,第一:防止重复提交:第二:最简单. 于是磊哥问他,是单机环境还是分布式环境? 得到的反馈是单机 ...

  10. click vue 重复调用_VUE防止多次点击,重复请求

    VUE防止多次点击,重复请求 1.添加自定义文件 preventReClick.js import Vue from 'vue' const preventReClick = Vue.directiv ...

最新文章

  1. 关于TypeError: ‘function‘ object is not subscriptable 报错的解决方法
  2. 网页转变成app,隐藏浏览器地址栏
  3. Windows服务器下升级PHP版本的方法
  4. bzoj3522 Hotel
  5. 我的SQL SERVER数据库会装满吗?
  6. Java基础----对象与类
  7. Json,Hashlib与Base64(占坑待补)
  8. 分页原理+软件架构师
  9. v8学习笔记(四) 对象机制
  10. jeesite3环境部署时初始化数据库注意问题
  11. 开发日记:接口开发设计
  12. 存储引擎和Mysql服务层出现索引信息不一致错误提示
  13. Form 表单提交参数
  14. 睡后收益 -- CSDN博客打赏功能及自定义模块以及代码分享
  15. 圆柱体积怎么算立方公式_圆柱体积公式是什么,怎么算,
  16. 华为mate40和mate40pro哪个更值得入手-华为mate40和mate40pro的性价比-华为mate40和mate40pro的区别
  17. mysql餐馆点餐系统_课内资源 - 基于Jsp和MySql的餐厅点餐系统
  18. 忍不住吐个槽:985硕,2021年毕业入职某国企,月薪不到一万,年终奖490元!
  19. Mean ± SEM or Mean(SD)
  20. long数据类型java_[二]基础数据类型之Long详解

热门文章

  1. 预测房价实验-房价数据集
  2. 百度ueditor编辑器控制图片在编辑框中的大小
  3. java迷宫注释_写下走迷宫游戏的注释
  4. Kali——绕过杀毒软件检测工具Veil-Evasion
  5. 笔记本风扇噪音大的解决方法
  6. 2022年11月网络工程师考试知识点分布
  7. 本周工作心得系列(5)
  8. 这些行业高薪职位最多
  9. Error: Cannot find module ‘@/xxx‘
  10. 有什么适合小团队的协作工具?