当前位置:首页 > 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实现树结构的方法 在PHP中实现树结构通常可以通过递归或迭代的方式完成。以下是几种常见的实现方法: 递归实现树结构 递归是处理树结构的自然方式,尤其适用于具有未知深度的树。 class Tr…

git php实现

git php实现

Git 与 PHP 的集成实现 使用 PHP 执行 Git 命令 通过 PHP 的 exec()、shell_exec() 或 passthru() 函数可以直接调用 Git 命令,适用于服务器端操作…

php实现websocket

php实现websocket

PHP 实现 WebSocket WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。PHP 可以通过多种方式实现 WebSocket 功能,以下是几种常见的方法: 使用 Ratc…

php实现上传

php实现上传

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

php 登录实现

php 登录实现

PHP 登录实现 PHP 登录功能通常包括用户认证、会话管理和安全性措施。以下是实现 PHP 登录功能的关键步骤。 数据库准备 创建一个用户表存储用户信息,通常包括用户名、密码(加密存储)和其他必要…