当前位置:首页 > PHP

php实现限流

2026-01-29 19:25:24PHP

PHP 实现限流的方法

计数器法

计数器法是最简单的限流算法,通过统计单位时间内的请求次数来判断是否超过阈值。

class CounterLimiter {
    private $limit;
    private $interval;
    private $count = 0;
    private $lastResetTime;

    public function __construct($limit, $interval) {
        $this->limit = $limit;
        $this->interval = $interval;
        $this->lastResetTime = time();
    }

    public function allowRequest() {
        $currentTime = time();
        if ($currentTime - $this->lastResetTime > $this->interval) {
            $this->count = 0;
            $this->lastResetTime = $currentTime;
        }
        if ($this->count < $this->limit) {
            $this->count++;
            return true;
        }
        return false;
    }
}

滑动窗口法

滑动窗口法是对计数器法的改进,可以更精确地控制单位时间内的请求量。

php实现限流

class SlidingWindowLimiter {
    private $limit;
    private $interval;
    private $requests = [];

    public function __construct($limit, $interval) {
        $this->limit = $limit;
        $this->interval = $interval;
    }

    public function allowRequest() {
        $currentTime = time();
        $this->requests[] = $currentTime;
        while (!empty($this->requests) && $currentTime - $this->requests[0] > $this->interval) {
            array_shift($this->requests);
        }
        return count($this->requests) <= $this->limit;
    }
}

令牌桶算法

令牌桶算法允许突发流量,通过定期向桶中添加令牌来控制请求速率。

php实现限流

class TokenBucketLimiter {
    private $capacity;
    private $tokens;
    private $rate;
    private $lastTime;

    public function __construct($capacity, $rate) {
        $this->capacity = $capacity;
        $this->tokens = $capacity;
        $this->rate = $rate;
        $this->lastTime = time();
    }

    public function allowRequest() {
        $currentTime = time();
        $elapsed = $currentTime - $this->lastTime;
        $this->tokens = min($this->capacity, $this->tokens + $elapsed * $this->rate);
        $this->lastTime = $currentTime;
        if ($this->tokens >= 1) {
            $this->tokens--;
            return true;
        }
        return false;
    }
}

Redis 实现分布式限流

在分布式环境中,可以使用 Redis 实现限流,确保多个服务节点之间的限流一致性。

class RedisLimiter {
    private $redis;
    private $key;
    private $limit;
    private $interval;

    public function __construct($redis, $key, $limit, $interval) {
        $this->redis = $redis;
        $this->key = $key;
        $this->limit = $limit;
        $this->interval = $interval;
    }

    public function allowRequest() {
        $currentTime = time();
        $this->redis->zRemRangeByScore($this->key, 0, $currentTime - $this->interval);
        $count = $this->redis->zCard($this->key);
        if ($count < $this->limit) {
            $this->redis->zAdd($this->key, $currentTime, uniqid());
            return true;
        }
        return false;
    }
}

使用框架中间件

在 Laravel 等框架中,可以使用中间件实现限流功能。

namespace App\Http\Middleware;

use Closure;
use Illuminate\Cache\RateLimiter;
use Symfony\Component\HttpFoundation\Response;

class ThrottleRequests {
    protected $limiter;

    public function __construct(RateLimiter $limiter) {
        $this->limiter = $limiter;
    }

    public function handle($request, Closure $next, $maxAttempts = 60, $decayMinutes = 1) {
        $key = $request->ip();
        if ($this->limiter->tooManyAttempts($key, $maxAttempts)) {
            return new Response('Too Many Attempts', 429);
        }
        $this->limiter->hit($key, $decayMinutes * 60);
        return $next($request);
    }
}

以上方法可以根据实际需求选择适合的限流策略,单机环境下可以使用内存限流,分布式环境下建议使用 Redis 实现。

标签: php
分享给朋友:

相关文章

php实现验证码

php实现验证码

PHP实现验证码的方法 使用GD库生成验证码 GD库是PHP中处理图像的扩展,可用于生成验证码图片。 <?php session_start(); $width = 120; $height…

php实现上传

php实现上传

PHP 文件上传实现 HTML 表单设置 创建一个包含文件上传字段的 HTML 表单,确保表单的 enctype 属性设置为 multipart/form-data,这是文件上传必需的设置。 <…

php 实现登录

php 实现登录

PHP 登录功能实现 使用 PHP 实现登录功能通常需要结合数据库验证和会话管理。以下是一个基本的登录实现流程: 数据库准备 创建用户表存储用户名和密码(建议使用哈希加密): CREATE TAB…

php实现定时

php实现定时

PHP 实现定时任务的方法 PHP 本身是脚本语言,通常需要借助外部工具或框架实现定时任务。以下是几种常见方法: 使用 Cron 任务 Linux 系统自带的 Cron 是常用的定时任务工具。通过编…

php数组实现

php数组实现

PHP 数组的基本实现 PHP 数组是一种非常灵活的数据结构,可以存储多个值,并且支持多种类型的键(整数或字符串)。PHP 数组实际上是有序映射(ordered map),可以看作是列表(vector…

php 实现md5

php 实现md5

使用 PHP 内置函数实现 MD5 PHP 提供了 md5() 函数,可以直接计算字符串的 MD5 哈希值。该函数接受一个字符串参数,返回 32 字符的十六进制哈希值。 $string = "H…