PHP 实现防抖功能(防重复请求)
PHP 实现防抖功能(防重复请求)
原理
- 使用Redis做接口访问锁,访问前加锁,访问结束后解锁。
- 使用 域名+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);});}
}
使用示例
- 如果是能使用auth()->id()获得用户ID的接口
antiRepeat();...业务代码
- 如果是不能使用auth()->id()获得用户ID的接口
$user_id = 1;// 自行设置用户ID
antiRepeat($user_id);...业务代码
by 同事 - kaivin99
PHP 实现防抖功能(防重复请求)相关推荐
- spring 注解重复(防重复请求)
1.配置拦截器 spring-mvc.xml <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/ ...
- 防止跨站请求伪造(CSRF)攻击 和 防重复提交 的方法的实现
CSRF的概念可以参考:http://netsecurity.51cto.com/art/200812/102951.htm 本文介绍的是基于spring拦截器的Spring MVC实现 首先配置拦截 ...
- 利用redis实现分布式请求防重复提交
2019独角兽企业重金招聘Python工程师标准>>> 1.自定义注解类Token @Target(ElementType.METHOD) @Retention(RetentionP ...
- springboot 主键重复导致数据重复_Springboot实现防重复提交和防重复点击(附源码)...
背景# 同一条数据被用户点击了多次,导致数据冗余,需要防止弱网络等环境下的重复点击 目标# 通过在指定的接口处添加注解,实现根据指定的接口参数来防重复点击 说明# 这里的重复点击是指在指定的时间段内多 ...
- 分布式架构:并发重复请求和幂等场景技术实现总结
分布式架构:并发重复请求和幂等场景技术实现总结 原文:分布式架构:并发重复请求和幂等场景技术实现总结 概念 重复请求是指一个请求因为某些原因被多次提交,场景简述如下: 1)用户快速多次点击按钮 2)N ...
- 防重复请求处理的实践与总结
#防重复处理总结 ##背景 在业务开发中,我们常会面对防止重复请求的问题.当服务端对于请求的响应涉及数据的修改,或状态的变更时,可能会造成极大的危害.重复请求的后果在交易系统.售后维权,以及支付系统中 ...
- redis+aop防重复提交
文章目录 1.防重复提交注解 2.redis分布式锁 3.防止重复提交Aop 之前有记录一篇用redis+拦截器防重复提交的内容: redis+拦截器防重复提交 1.防重复提交注解 @Target(E ...
- 由防重复点击引发的幂等性问题思考
HTTP/1.1中对幂等性的定义是:一次和多次请求某一个资源对于资源本身应该具有同样的结果(网络超时等问题除外).也就是说,用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而 ...
- java mysql防重复提交_防止数据重复提交的6种方法(超简单)!
有位朋友,某天突然问磊哥:在 Java 中,防止重复提交最简单的方案是什么? 这句话中包含了两个关键信息,第一:防止重复提交:第二:最简单. 于是磊哥问他,是单机环境还是分布式环境? 得到的反馈是单机 ...
- click vue 重复调用_VUE防止多次点击,重复请求
VUE防止多次点击,重复请求 1.添加自定义文件 preventReClick.js import Vue from 'vue' const preventReClick = Vue.directiv ...
最新文章
- 关于TypeError: ‘function‘ object is not subscriptable 报错的解决方法
- 网页转变成app,隐藏浏览器地址栏
- Windows服务器下升级PHP版本的方法
- bzoj3522 Hotel
- 我的SQL SERVER数据库会装满吗?
- Java基础----对象与类
- Json,Hashlib与Base64(占坑待补)
- 分页原理+软件架构师
- v8学习笔记(四) 对象机制
- jeesite3环境部署时初始化数据库注意问题
- 开发日记:接口开发设计
- 存储引擎和Mysql服务层出现索引信息不一致错误提示
- Form 表单提交参数
- 睡后收益 -- CSDN博客打赏功能及自定义模块以及代码分享
- 圆柱体积怎么算立方公式_圆柱体积公式是什么,怎么算,
- 华为mate40和mate40pro哪个更值得入手-华为mate40和mate40pro的性价比-华为mate40和mate40pro的区别
- mysql餐馆点餐系统_课内资源 - 基于Jsp和MySql的餐厅点餐系统
- 忍不住吐个槽:985硕,2021年毕业入职某国企,月薪不到一万,年终奖490元!
- Mean ± SEM or Mean(SD)
- long数据类型java_[二]基础数据类型之Long详解