PHP中的速率限制:通过请求频率限制保护网站

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

PHP中的速率限制:防止过载的完整指南



速率限制(请求频率限制)是一种至关重要的Web应用保护机制。它可以防止服务器资源被滥用,抵御DDoS攻击、密码暴力破解和垃圾信息。在PHP中,有几种有效的方法和库可以实现速率限制。本文将介绍最佳工具、工作原理和实际示例。



什么是速率限制以及为什么需要它?

速率限制规定了客户端(IP地址、用户或API密钥)在特定时间段内可以执行的最大请求数。主要目标:

  • DDoS防护 — 防止机器人导致服务器过载
  • 防止暴力破解 — 限制登录尝试次数
  • 公平资源分配 — 所有用户享有平等访问权
  • 节省服务器资源 — 降低数据库和CPU负载


流行的速率限制算法

在选择库之前,了解基本算法很重要:

  • 令牌桶 — 以特定速率积累令牌,允许短时流量突发
  • 漏桶 — 以恒定速率处理请求,平滑流量
  • 固定窗口 — 在固定时间间隔内统计请求数
  • 滑动窗口 — 更精确的版本,在滑动时间窗口内统计请求


PHP中最佳的速率限制库



1. Symfony Rate Limiter

Symfony官方组件,可独立于框架使用。支持Redis、APCu和文件存储。

composer require symfony/rate-limiter

使用示例:

<?phpuse Symfony\\Component\\RateLimiter\\RateLimiterFactory;use Symfony\\Component\\RateLimiter\\Storage\\InMemoryStorage;

$factory = new RateLimiterFactory([ 'id' => 'login', 'policy' => 'token_bucket', 'limit' => 10, 'rate' => ['interval' => '1 minute'],], new InMemoryStorage());

$limiter = $factory->create('user_123');

if ($limiter->consume()->isAccepted()) { // 允许请求 echo "访问已允许";} else { // 拒绝请求 http_response_code(429); echo "请求过多";}?>


2. PHP RateLimiter (by bantu)

适用于简单场景的轻量级库。支持Redis、Memcached和文件。

composer require bantu/php-ratelimiter

示例:

<?phpuse bantu\\RateLimiter\\RateLimiterFactory;

$factory = new RateLimiterFactory();$limiter = $factory->createRedisRateLimiter( new \\Predis\\Client(), 'api_limit', 100, // 请求限制 3600 // 时间窗口(秒));

if ($limiter->hit($_SERVER['REMOTE_ADDR'])) { echo "请求已接受";} else { http_response_code(429); echo "已达限制";}?>


3. GrahamCampbell/Laravel RateLimiter

如果您使用Laravel,这是原生解决方案。从版本8开始内置在框架中。

<?phpuse Illuminate\\Support\\Facades\\RateLimiter;

// 在AppServiceProvider中定义限流器RateLimiter::for('api', function ($job) { return \\Illuminate\\Cache\\RateLimiting\\Limit::perMinute(60)->by($job->user->id ?: $job->ip());});

// 在控制器中使用public function store(Request $request){ if (RateLimiter::tooManyAttempts('send-message:'.$request->ip(), 5)) { return response('消息过多', 429)

推荐