qnvip-com / php-rate-limit-middleware
A PHP middleware package for rate limiting and IP filtering with CIDR support
Installs: 9
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/qnvip-com/php-rate-limit-middleware
Requires
- php: >=7.1
Requires (Dev)
- phpunit/phpunit: ^7.0|^8.0|^9.0
Suggests
- ext-redis: Required for rate limiting functionality
- phpredis/phpredis: A PHP extension for Redis
This package is not auto-updated.
Last update: 2025-11-24 08:32:06 UTC
README
一个用于请求频率限制和IP过滤的PHP中间件包。
功能特性
- IP 白名单和黑名单(支持 IPv4/IPv6 网段)
- 请求频率限制(基于 Redis)
- 自动黑名单机制(可配置启用/禁用)
- Redis 异常容错处理
- 可配置的策略执行模式(阻止/非阻止)
- 全面的策略节点日志记录
- 中间件集成
- 可自定义的日志处理器(支持 PSR-3 标准)
- 请求数最大值跟踪记录到文件或Redis
版本
当前版本: 1.1.0
查看 CHANGELOG.md 了解详细的版本历史。
安装
使用Composer安装:
composer require php-rate-limit-middleware/php-rate-limit-middleware
Redis 扩展要求
如果要使用限流功能,需要安装 Redis 扩展:
Windows:
- 下载适合您PHP版本的 php_redis.dll
- 将其放置在 PHP 扩展目录中
- 在 php.ini 中添加:
extension=php_redis.dll - 重启 Web 服务器
Linux/macOS (使用 PECL):
pecl install redis
然后在 php.ini 中添加: extension=redis
使用 Composer 替代方案
如果不方便安装 PHP 扩展,可以使用 Composer 包作为替代:
composer require phpredis/phpredis
使用方法
<?php use QnvipCom\PhpRateLimitMiddleware\Config\Config; use QnvipCom\PhpRateLimitMiddleware\RateLimit\RateLimiter; use QnvipCom\PhpRateLimitMiddleware\Middleware\FilterMiddleware; // 加载配置 $config = Config::load(); // 初始化Redis连接 $redis = new Redis(); $redis->connect('127.0.0.1', 6379); // 创建速率限制器实例(可选地指定键前缀) $rateLimiter = new RateLimiter($redis, $config['rate_limit'], 'myapp_rate_limit'); // 创建中间件实例 $middleware = new FilterMiddleware($config, $rateLimiter); // 在您的应用中使用中间件处理请求 $response = $middleware->handle($request, function($req) { // 处理实际业务逻辑 return $next($req); }); // 手动管理自动黑名单 if ($rateLimiter->isIpAutoBlacklisted('192.168.1.100')) { echo "IP 192.168.1.100 在自动黑名单中"; } // 手动将IP从自动黑名单中移除 $rateLimiter->removeFromAutoBlacklist('192.168.1.100'); // 获取所有自动黑名单中的IP $blacklistedIps = $rateLimiter->getAutoBlacklist();
在 Laravel 中使用自定义日志处理器
<?php use QnvipCom\PhpRateLimitMiddleware\Config\Config; use QnvipCom\PhpRateLimitMiddleware\RateLimit\RateLimiter; use QnvipCom\PhpRateLimitMiddleware\Middleware\FilterMiddleware; use QnvipCom\PhpRateLimitMiddleware\Logger\LoggerInterface; // 创建一个适配 Laravel 日志系统的日志处理器 class LaravelLogger implements LoggerInterface { private $logger; public function __construct(\Illuminate\Log\LogManager $logger) { $this->logger = $logger; } public function emergency(string $message, array $context = []): void { $this->logger->emergency($message, $context); } public function alert(string $message, array $context = []): void { $this->logger->alert($message, $context); } public function critical(string $message, array $context = []): void { $this->logger->critical($message, $context); } public function error(string $message, array $context = []): void { $this->logger->error($message, $context); } public function warning(string $message, array $context = []): void { $this->logger->warning($message, $context); } public function notice(string $message, array $context = []): void { $this->logger->notice($message, $context); } public function info(string $message, array $context = []): void { $this->logger->info($message, $context); } public function debug(string $message, array $context = []): void { $this->logger->debug($message, $context); } public function log($level, string $message, array $context = []): void { $this->logger->log($level, $message, $context); } } // 加载配置 $config = Config::load(); // 初始化Redis连接 $redis = new Redis(); $redis->connect('127.0.0.1', 6379); // 创建自定义日志处理器 $logger = new LaravelLogger(app('log')); // 创建速率限制器实例(可选地指定键前缀) $rateLimiter = new RateLimiter($redis, $config['rate_limit'], 'myapp_rate_limit', $logger); // 创建中间件实例 $middleware = new FilterMiddleware($config, $rateLimiter, $logger);
在 ThinkPHP5 中使用自定义日志处理器
<?php use QnvipCom\PhpRateLimitMiddleware\Config\Config; use QnvipCom\PhpRateLimitMiddleware\RateLimit\RateLimiter; use QnvipCom\PhpRateLimitMiddleware\Middleware\FilterMiddleware; use QnvipCom\PhpRateLimitMiddleware\Logger\LoggerInterface; // 创建一个适配 ThinkPHP5 日志系统的日志处理器 class ThinkPHPLogger implements LoggerInterface { public function emergency(string $message, array $context = []): void { \think\facade\Log::emergency($message, $context); } public function alert(string $message, array $context = []): void { \think\facade\Log::alert($message, $context); } public function critical(string $message, array $context = []): void { \think\facade\Log::critical($message, $context); } public function error(string $message, array $context = []): void { \think\facade\Log::error($message, $context); } public function warning(string $message, array $context = []): void { \think\facade\Log::warning($message, $context); } public function notice(string $message, array $context = []): void { \think\facade\Log::notice($message, $context); } public function info(string $message, array $context = []): void { \think\facade\Log::info($message, $context); } public function debug(string $message, array $context = []): void { \think\facade\Log::debug($message, $context); } public function log($level, string $message, array $context = []): void { \think\facade\Log::record($message, $level, $context); } } // 加载配置 $config = Config::load(); // 初始化Redis连接 $redis = new Redis(); $redis->connect('127.0.0.1', 6379); // 创建自定义日志处理器 $logger = new ThinkPHPLogger(); // 创建速率限制器实例(可选地指定键前缀) $rateLimiter = new RateLimiter($redis, $config['rate_limit'], 'myapp_rate_limit', $logger); // 创建中间件实例 $middleware = new FilterMiddleware($config, $rateLimiter, $logger);
配置说明
默认配置包含以下选项:
ip_whitelist: IP白名单列表(支持精确IP地址和CIDR网段格式,如:192.168.0.0/16,也支持IPv6)ip_blacklist: IP黑名单列表(支持精确IP地址和CIDR网段格式,如:172.16.0.0/12,也支持IPv6)rate_limit.limit: 时间窗口内最大请求数rate_limit.duration: 时间窗口长度(秒)auto_blacklist.threshold: 自动加入黑名单的请求阈值(每时间窗口内的请求数)auto_blacklist.duration: 自动黑名单持续时间(秒)
您可以根据需要修改这些配置值。
自动黑名单配置
'auto_blacklist' => [ 'enabled' => true, // 是否启用自动黑名单功能 'threshold' => 100, // 触发自动黑名单的阈值(每分钟请求数) 'duration' => 3600, // 自动黑名单持续时间(秒),默认1小时,设为0或负数表示永久 ]
当某个 IP 在单位时间内的请求次数超过阈值时,会自动加入黑名单并在指定时间后自动解除。
若将 duration 设置为 0 或负数,则该 IP 会被永久列入黑名单,除非手动移除。
中间件行为配置
'middleware' => [ 'block_on_violation' => true, // 是否在违反策略时阻止访问 'log_policy_violations' => true, // 是否记录策略违规日志 ]
默认情况下,当检测到违反策略的行为时(如IP在黑名单中、触发限流、在自动黑名单中),系统会阻止访问并返回相应的错误码。
当设置为 false 时,系统只会记录违规行为但允许访问继续进行,这在某些测试或监控场景中非常有用。
限流器详细日志配置
'rate_limit' => [ 'limit' => 60, // 最大请求次数 'duration' => 60, // 时间窗口(秒) 'log_detailed' => true, // 是否记录详细日志 ]
当 log_detailed 设置为 true 时,限流器会记录更详细的日志信息,包括请求计数、限制值等。
请求数最大值跟踪配置
'request_count_tracking' => [ 'enabled' => false, // 是否启用请求数跟踪 'storage' => 'file', // 存储方式: 'file' 或 'redis' 'max_count_file' => '', // 存储最大请求数的文件路径 (当storage为'file'时使用) 'max_count_redis_key' => '' // 存储最大请求数的Redis键 (当storage为'redis'时使用) ]
当启用请求数跟踪功能时,系统会将每个时间窗口内的最大请求数记录到指定的存储中(文件或Redis)。 这有助于监控系统负载和峰值流量。
策略节点日志说明
系统会在以下关键节点记录日志:
- 请求开始处理时记录客户端IP
- IP白名单检查结果
- IP黑名单检查结果
- 自动黑名单检查结果
- 请求频率限制检查结果
- 最终处理结果(允许/拒绝)
默认情况下,日志通过 PHP 的 error_log 函数记录,可以通过配置 PHP 的 error_log 指令将日志输出到指定文件。
如果提供了自定义的日志处理器,则会使用该处理器记录日志。
Redis 异常处理
当 Redis 出现连接异常或其他错误时,系统会记录错误日志但不会中断正常业务流程:
- IP 白名单/黑名单检查不受影响
- 请求频率限制会暂时跳过,允许请求通过
- 自动黑名单检查会暂时跳过,允许请求通过
- 所有 Redis 操作都有异常捕获,确保服务持续可用
运行测试
要运行测试,需要先安装开发依赖:
composer install
然后可以通过以下方式运行测试:
使用 PHPUnit 直接运行
./vendor/bin/phpunit
使用 Composer 脚本运行
composer test
在 Windows 系统上运行
test.bat
在 Unix/Linux/macOS 系统上运行
./test.sh
运行特定测试类
./vendor/bin/phpunit tests/RateLimit/RateLimiterTest.php ./vendor/bin/phpunit tests/Middleware/FilterMiddlewareTest.php ./vendor/bin/phpunit tests/Middleware/IpMatchingTest.php ./vendor/bin/phpunit tests/Middleware/AutoBlacklistTest.php
注意:测试需要 Redis 服务器运行在本地默认端口(6379)上。
发布
要发布新版本,请更新以下文件:
- composer.json 中的版本号
- CHANGELOG.md 中的变更记录
- 使用 Git tag 标记新版本
许可证
本项目采用 MIT 许可证授权。