PHP防抖(防重复提交)简单实现
PHP防抖(防重复提交)简单实现
本文编写时间:2023-06-05
需求
前端有时表单未做防抖处理,会给后端同时传递重复请求,希望后端代码能屏蔽。
实现:
这里给出本人的非常简单的实现。主要是针对简单需求的。复杂的需求代码肯定没这么简单。
前提:需安装redis。
欢迎各种讨论。
代码部分
仅供参考
异常类
/**
* 防抖异常。这个类留空就行。
*/
class AntiRepeatException extends Exception
{
}
//下面:框架的异常集中处理,自定义 的。这里是tp的。larave类似。
namespace app\common\exception;
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);
}
}
下面是通用的防抖类。
namespace app\services\system;
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
下面是使用示例
class TestController extends Controller
{
// 假设该控制器的方法需要对登录用户限流 or 防抖。
public function index444()
{
$user_id = Auth::id();// 得到当前登录用户。
AntiRepeat::handle($user_id);
// 下面做该接口正常的功能实现。
// 。。。
// 。。。
return 'ok';
}
}
总结
- 这代码只能应付简单的需求,用于一些用户下订单之类的重要操作。
- 限流是大概念,防抖可以看成某种简单的限流实现。
- 即可针对单个登录用户,也可以对所有请求,但实际后者意义不大。
- 后端独立实现,无需前端配合
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: