PHP 语言 实现简单的API限流

PHP阿木 发布于 2025-07-01 7 次阅读


PHP API限流实现技术详解

随着互联网的快速发展,API(应用程序编程接口)已经成为现代软件开发中不可或缺的一部分。随着API使用量的增加,如何保证API服务的稳定性和响应速度,防止恶意攻击和过度使用,成为了开发者面临的重要问题。限流(Rate Limiting)技术应运而生,它通过限制用户在一定时间内对API的访问次数,来保护服务器资源,提高服务质量和用户体验。本文将围绕PHP语言,详细介绍API限流的实现技术。

限流的基本原理

限流的基本原理是:在用户访问API时,记录其访问次数,当访问次数超过预设的限制时,拒绝服务或返回错误信息。常见的限流策略包括:

1. 固定窗口限流:在固定的时间窗口内,限制用户访问次数。

2. 滑动窗口限流:在滑动的时间窗口内,限制用户访问次数。

3. 令牌桶限流:使用令牌桶算法,控制用户访问速率。

4. 漏桶限流:使用漏桶算法,控制用户访问速率。

PHP实现固定窗口限流

以下是一个简单的PHP固定窗口限流实现示例:

php

<?php


class RateLimiter {


private $maxRequests;


private $timeWindow;


private $storage;

public function __construct($maxRequests, $timeWindow) {


$this->maxRequests = $maxRequests;


$this->timeWindow = $timeWindow;


$this->storage = [];


}

public function isAllowed($userId) {


$currentTime = time();


$windowStart = $currentTime - $this->timeWindow;

// 清理过期的访问记录


$this->storage = array_filter($this->storage, function ($timestamp) use ($windowStart) {


return $timestamp > $windowStart;


});

// 检查当前用户的访问次数


if (!isset($this->storage[$userId])) {


$this->storage[$userId] = 0;


}

if ($this->storage[$userId] < $this->maxRequests) {


$this->storage[$userId]++;


return true;


} else {


return false;


}


}


}

// 使用示例


$rateLimiter = new RateLimiter(5, 60); // 每分钟最多5次请求


if ($rateLimiter->isAllowed('user123')) {


// 允许访问API


echo "Access granted.";


} else {


// 拒绝访问


http_response_code(429);


echo "Too many requests. Please try again later.";


}


?>


PHP实现滑动窗口限流

滑动窗口限流与固定窗口限流类似,但不需要清理过期的访问记录。以下是一个简单的PHP滑动窗口限流实现示例:

php

<?php


class RateLimiter {


private $maxRequests;


private $timeWindow;


private $storage;

public function __construct($maxRequests, $timeWindow) {


$this->maxRequests = $maxRequests;


$this->timeWindow = $timeWindow;


$this->storage = [];


}

public function isAllowed($userId) {


$currentTime = time();


$windowStart = $currentTime - $this->timeWindow;

// 移除窗口之外的访问记录


$this->storage = array_filter($this->storage, function ($timestamp) use ($windowStart) {


return $timestamp >= $windowStart;


});

// 检查当前用户的访问次数


if (!isset($this->storage[$userId])) {


$this->storage[$userId] = 0;


}

if ($this->storage[$userId] < $this->maxRequests) {


$this->storage[$userId]++;


return true;


} else {


return false;


}


}


}

// 使用示例


$rateLimiter = new RateLimiter(5, 60); // 每分钟最多5次请求


if ($rateLimiter->isAllowed('user123')) {


// 允许访问API


echo "Access granted.";


} else {


// 拒绝访问


http_response_code(429);


echo "Too many requests. Please try again later.";


}


?>


PHP实现令牌桶限流

令牌桶算法是一种动态限流策略,它允许一定速率的流量通过,同时可以应对短时间内的突发流量。以下是一个简单的PHP令牌桶限流实现示例:

php

<?php


class TokenBucket {


private $tokens;


private $maxTokens;


private $fillInterval;


private $lastFillTime;

public function __construct($maxTokens, $fillInterval) {


$this->maxTokens = $maxTokens;


$this->fillInterval = $fillInterval;


$this->tokens = $this->maxTokens;


$this->lastFillTime = time();


}

public function consume($numTokens) {


$currentTime = time();


$timePassed = $currentTime - $this->lastFillTime;


$tokensToAdd = floor($timePassed / $this->fillInterval) ($this->maxTokens / $this->fillInterval);


$this->tokens = min($this->maxTokens, $this->tokens + $tokensToAdd);


$this->lastFillTime = $currentTime;

if ($this->tokens >= $numTokens) {


$this->tokens -= $numTokens;


return true;


} else {


return false;


}


}


}

// 使用示例


$tokenBucket = new TokenBucket(5, 1); // 每秒最多5个令牌


if ($tokenBucket->consume(1)) {


// 允许访问API


echo "Access granted.";


} else {


// 拒绝访问


http_response_code(429);


echo "Too many requests. Please try again later.";


}


?>


总结

本文介绍了PHP语言中实现API限流的几种技术,包括固定窗口限流、滑动窗口限流和令牌桶限流。这些技术可以帮助开发者保护服务器资源,提高API服务的稳定性和响应速度。在实际应用中,可以根据具体需求选择合适的限流策略,并结合缓存、数据库等技术实现更复杂的限流逻辑。