前言

因为我自己上线了一个免费的API接口站,想利用Redis来限制恶意调用、爬虫等情况,所以写了这么一个类。

代码

<?php
/**
 * @function:Re拦截器
 * @author:木小果
 * @link:https://blog.muxiaoguo.cn
 * @date:2022/2/27
 */
class ReInterceptor {
    public $redis;
    public $cycle;
    public $limit;
    public $outtime;
    
    /**
     * 初始化Redis
     * @param   string  $pass   密码
     * @param   string  $ip     IP
     * @param   int     $port   端口
     */
    public function __construct($pass,$ip='127.0.0.1',$port=6379) {
        $this->redis = new Redis();
        $this->redis->connect($ip, $port);
        $this->redis->auth($pass);
        if ($this->redis->ping() != '+PONG') die("Redis abnormal");
    }
    
    
    /**
     * 设置Redis限制参数
     * @param   int $cycle      一个周期时长,单位:毫秒
     * @param   int $limit      一个周期内访问数量上限,单位:次
     * @param   int $outtime    限制用户访问的时间,单位:秒
     * @return  null
     */
    public function setReCof($cycle,$limit,$outtime) {
        $this->cycle = $cycle;
        $this->limit = $limit;
        $this->outtime = $outtime;
    }
    
    
    /**
     * 检查KEY
     * @param   string  $key        用户唯一ID
     * @return  int     $result     周期内调用次数
     */
    public function check($key) {
        if ($this->redis->exists($key)) {
            $this->redis->incr($key);
            $count = $this->redis->get($key);
            if ($count > $this->limit) {
                $this->redis->expire($key, $this->outtime);
                $rem = $this->redis->pttl($key);
                $msg = '请求频繁,请在 [time] 秒后再试';
                $msg = str_replace('[time]',($rem / 1000), $msg);
                die($this->proMessage(3301,$msg));
            }
            return $count;
        } else {
            $this->redis->incr($key,0);
            $this->redis->pexpire($key, $this->cycle);
        }
        return $this->redis->get($key);
    }
    
    
    /**
     * 返回JSON提示语(提示消息)
     * @param   int     $code   错误代码
     * @param   string  $msg    错误内容
     * @return  string  $result 返回数据
     */
    public function proMessage($code, $msg, $data=[]) {
        $result = [//返回数据统一处理
            'code' => $code,
            'msg' => $msg,
            'data' => $data
        ];
        return json_encode($result,320);
    }
}
?>

用法

/*实例化*/
$redis = new ReInterceptor('redisPassword');
/*设置基本参数,解释:1000毫秒内调用次数超过5次封禁用户30秒*/
$redis->setReCof(1000, 5, 30);
/*检查KEY*/
$count = $redis->check(getRealIp());
echo '周期内调用次数:' . $count;

最后修改:2022 年 02 月 09 日
如果觉得我的文章对你有用,请随意赞赏