snapflowio/ratelimit

A simple and lightweight library for protecting resources with time limits.

Installs: 1

Dependents: 0

Suggesters: 0

Security: 0

Stars: 1

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/snapflowio/ratelimit

v0.1.0 2025-12-16 23:16 UTC

This package is auto-updated.

Last update: 2025-12-16 23:18:43 UTC


README

A simple and lightweight library for protecting resources with time limits.

Installation

composer require snapflowio/ratelimit

Quick Start

Basic Rate Limiting

<?php

use Snapflow\Ratelimit\Ratelimit;
use Snapflow\Ratelimit\Adapters\TimeLimit\RedisAdapter;

// Connect to Redis
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);

// Create adapter: 100 requests per 60 seconds
$adapter = new RedisAdapter(
    key: 'api_requests',
    limit: 100,
    seconds: 60,
    redis: $redis
);

$ratelimit = new Ratelimit($adapter);

// Check if request should be blocked
if ($ratelimit->check()) {
    http_response_code(429);
    die('Rate limit exceeded. Please try again later.');
}

// Process the request...
echo "Request processed successfully!";

IP-Based Rate Limiting

<?php

use Snapflow\Ratelimit\Ratelimit;
use Snapflow\Ratelimit\Adapters\TimeLimit\RedisAdapter;

$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);

// Rate limit by IP address: 5 login attempts per 5 minutes
$adapter = new RedisAdapter(
    key: 'login_{ip}',
    limit: 5,
    seconds: 300,
    redis: $redis
);

// Set the IP address dynamically
$adapter->setParam('{ip}', $_SERVER['REMOTE_ADDR']);

$ratelimit = new Ratelimit($adapter);

if ($ratelimit->check()) {
    die('Too many login attempts. Please try again in 5 minutes.');
}

// Show remaining attempts
echo "Remaining attempts: " . $adapter->remaining();

User-Specific Rate Limiting

<?php

use Snapflow\Ratelimit\Ratelimit;
use Snapflow\Ratelimit\Adapters\TimeLimit\RedisAdapter;

$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);

// Rate limit per user per endpoint
$adapter = new RedisAdapter(
    key: 'user_{userId}_endpoint_{endpoint}',
    limit: 1000,
    seconds: 3600,
    redis: $redis
);

$adapter
    ->setParam('{userId}', $currentUserId)
    ->setParam('{endpoint}', '/api/posts');

$ratelimit = new Ratelimit($adapter);

if ($ratelimit->check()) {
    http_response_code(429);
    header('X-RateLimit-Limit: ' . $adapter->limit());
    header('X-RateLimit-Remaining: ' . $adapter->remaining());
    die('API rate limit exceeded');
}

Captcha Verification

<?php

use Snapflow\Ratelimit\Ratelimit;
use Snapflow\Ratelimit\Adapters\Captcha\ReCaptchaAdapter;
use Snapflow\Ratelimit\Adapters\Captcha\HCaptchaAdapter;
use Snapflow\Ratelimit\Adapters\Captcha\TurnstileAdapter;

// Google reCAPTCHA v3
$recaptcha = new ReCaptchaAdapter(
    secret: 'your-secret-key',
    response: $_POST['g-recaptcha-response'],
    remoteIP: $_SERVER['REMOTE_ADDR']
);

if (!$recaptcha->verify(score: 0.5)) {
    die('Bot detected!');
}

// hCaptcha
$hcaptcha = new HCaptchaAdapter(
    secret: 'your-hcaptcha-secret',
    response: $_POST['h-captcha-response'],
    remoteIP: $_SERVER['REMOTE_ADDR']
);

if (!$hcaptcha->verify()) {
    die('Verification failed!');
}

// Cloudflare Turnstile
$turnstile = new TurnstileAdapter(
    secret: 'your-turnstile-secret',
    response: $_POST['cf-turnstile-response'],
    remoteIP: $_SERVER['REMOTE_ADDR']
);

if (!$turnstile->verify()) {
    die('Challenge failed!');
}

Redis Cluster

<?php

use Snapflow\Ratelimit\Ratelimit;
use Snapflow\Ratelimit\Adapters\TimeLimit\RedisClusterAdapter;

$redisCluster = new \RedisCluster(
    null,
    ['127.0.0.1:7000', '127.0.0.1:7001', '127.0.0.1:7002']
);

$adapter = new RedisClusterAdapter(
    key: 'api_requests',
    limit: 10000,
    seconds: 3600,
    redis: $redisCluster
);

$ratelimit = new Ratelimit($adapter);

if ($ratelimit->check()) {
    die('Rate limit exceeded');
}

License

This library is available under the MIT License.

Copyright

Copyright (c) 2025 Snapflow