andrewdyer / predis-request-limiter
A framework-agnostic PHP library for rate limiting requests using Predis
Package info
github.com/andrewdyer/predis-request-limiter
pkg:composer/andrewdyer/predis-request-limiter
Requires
- php: ^8.3
- predis/predis: ^3.4
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.75
- phpunit/phpunit: ^10.5
README
A framework-agnostic PHP library for rate limiting requests using Predis.
Introduction
This library provides a request rate limiter for PHP applications, backed by Redis via Predis. The rate limit window, request threshold, storage key, and limit exceeded handler are all configurable, and any Predis-compatible client can be used as the backing store. The package is built on top of andrewdyer/php-package-template.
Prerequisites
- PHP: Version 8.3 or higher is required.
- Composer: Dependency management tool for PHP.
- Redis: A running Redis instance is required.
Installation
composer require andrewdyer/predis-request-limiter
Getting Started
1. Create a Predis client
use Predis\Client; $client = new Client([ 'scheme' => 'tcp', 'host' => '127.0.0.1', 'port' => 6379, ]);
2. Create a limiter
Instantiate Limiter with a Predis client and a unique identifier. The identifier is interpolated into the storage key to namespace requests per user, IP, or endpoint:
use AndrewDyer\PredisRequestLimiter\Limiter; $limiter = new Limiter($client, '127.0.0.1');
3. Configure the rate limit
Set the maximum number of requests and the time window in seconds:
$limiter->setRateLimit(requests: 10, perSecond: 60);
Usage
Checking and incrementing
Check whether the limit has been exceeded before incrementing the request count:
if ($limiter->hasExceededRateLimit()) { // Limit exceeded — respond with 429 or invoke the handler } else { $limiter->incrementRequestCount(); }
Setting a limit exceeded handler
Register a callable to invoke when the limit is exceeded:
$limiter->setLimitExceededHandler(function (): void { http_response_code(429); echo 'Too many requests.'; exit; });
Then invoke it when the limit is exceeded:
if ($limiter->hasExceededRateLimit()) { ($limiter->getLimitExceededHandler())(); } else { $limiter->incrementRequestCount(); }
Customising the storage key
The default storage key template is rate:%s:requests, where %s is replaced by the identifier. Override it to namespace keys differently:
$limiter->setStorageKey('api:limit:%s');
With the identifier 127.0.0.1, the resolved key becomes api:limit:127.0.0.1.
License
Licensed under the MIT licence and is free for private or commercial projects.