PHP code example of tobento / app-rate-limiter

1. Go to this page and download the library: Download tobento/app-rate-limiter library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

tobento / app-rate-limiter example snippets


use Tobento\App\AppFactory;
use Tobento\App\RateLimiter\RateLimiterCreatorInterface;
use Tobento\App\RateLimiter\RegistriesInterface;
use Tobento\App\RateLimiter\FingerprintInterface;

// Create the app
$app = (new AppFactory())->createApp();

// Add directories:
$app->dirs()
    ->dir(realpath(__DIR__.'/../'), 'root')
    ->dir(realpath(__DIR__.'/../app/'), 'app')
    ->dir($app->dir('app').'config', 'config', group: 'config')
    ->dir($app->dir('root').'public', 'public')
    ->dir($app->dir('root').'vendor', 'vendor');

// Adding boots:
$app->boot(\Tobento\App\RateLimiter\Boot\RateLimiter::class);
$app->booting();

// Implemented interfaces:
$limiterCreator = $app->get(RateLimiterCreatorInterface::class);
$registries = $app->get(RegistriesInterface::class);
$fingerprint = $app->get(FingerprintInterface::class);

// Run the app
$app->run();

use Tobento\App\AppFactory;
use Tobento\App\RateLimiter\RateLimiterCreatorInterface;
use Tobento\App\RateLimiter\Symfony\Registry\SlidingWindow;
use Tobento\App\Http\Exception\TooManyRequestsException;

$app = (new AppFactory())->createApp();

// Add directories:
$app->dirs()
    ->dir(realpath(__DIR__.'/../'), 'root')
    ->dir(realpath(__DIR__.'/../app/'), 'app')
    ->dir($app->dir('app').'config', 'config', group: 'config')
    ->dir($app->dir('root').'public', 'public')
    ->dir($app->dir('root').'vendor', 'vendor');

// Adding boots:
$app->boot(\Tobento\App\Http\Boot\ErrorHandler::class);
$app->boot(\Tobento\App\Http\Boot\Routing::class);
$app->boot(\Tobento\App\RateLimiter\Boot\RateLimiter::class);
$app->booting();

// Routes:
$app->route('POST', 'login', function(ServerRequestInterface $request, RateLimiterCreatorInterface $limiterCreator) {
    // create a rate limiter:
    $limiter = $limiterCreator->createFromRegistry(
        // a unique identifier of the client:
        id: $request->getServerParams()['REMOTE_ADDR'] ?? null,
        // define the rate limiter to use:
        registry: new SlidingWindow(limit: 5, interval: '5 minutes'),
    );

    // next hit the limiter and check if attempts exceeded:
    if ($limiter->hit()->isAttemptsExceeded()) {
        throw new TooManyRequestsException(
            retryAfter: $limiter->availableIn(),
            message: sprintf('Too Many Requests. Please retry after %d seconds.', $limiter->availableIn()),
            headers: [
                'X-RateLimit-Limit' => $limiter->maxAttempts(),
                'X-RateLimit-Remaining' => $limiter->remainingAttempts(),
                'X-RateLimit-Reset' => $limiter->availableAt()->getTimestamp(),
            ],
        );
    }

    // you may reset the attempts:
    // $limiter->reset();
    
    return 'response';
});

// Run the app:
$app->run();

use Tobento\App\AppFactory;
use Tobento\App\RateLimiter\Middleware\RateLimitRequests;
use Tobento\App\RateLimiter\Symfony\Registry\SlidingWindow;
use Tobento\App\Http\Exception\TooManyRequestsException;

$app = (new AppFactory())->createApp();

// Add directories:
$app->dirs()
    ->dir(realpath(__DIR__.'/../'), 'root')
    ->dir(realpath(__DIR__.'/../app/'), 'app')
    ->dir($app->dir('app').'config', 'config', group: 'config')
    ->dir($app->dir('root').'public', 'public')
    ->dir($app->dir('root').'vendor', 'vendor');

// Adding boots:
$app->boot(\Tobento\App\Http\Boot\ErrorHandler::class);
$app->boot(\Tobento\App\Http\Boot\Routing::class);
$app->boot(\Tobento\App\Http\Boot\RequesterResponser::class); // for redirection support
$app->boot(\Tobento\App\RateLimiter\Boot\RateLimiter::class);
$app->booting();

// Routes:
$app->route('POST', 'login', function() {
    // being rate limited!
    return 'response';
})->middleware([
    RateLimitRequests::class,
    
    // define the rate limiter to use:
    'registry' => new SlidingWindow(limit: 5, interval: '5 minutes'),
    
    // or by named rate limiter:
    //'registry' => 'login',
]);

$app->route('POST', 'register', function() {
    // being rate limited!
    return 'response';
})->middleware([
    RateLimitRequests::class,
    'registry' => new SlidingWindow(limit: 5, interval: '5 minutes'),
    
    // You may specify a redirect uri or route
    // which will redirect instead of throwing a TooManyRequestsException:
    'redirectUri' => '/register',
    'redirectRoute' => 'register',
    
    // You may specify a redirect message to be flashed.
    // The :seconds parameter value will be set by the middleware.
    'message' => 'Too many attempts. Please retry after :seconds seconds.',
    'messageLevel' => 'error', // default
    'messageKey' => 'email', // or null default
]);

// Run the app:
$app->run();

use Tobento\App\RateLimiter\Registry\Factory;
use Tobento\App\RateLimiter\Symfony\RateLimiterFactory;

$limiter = $limiterCreator->createFromRegistry(
    id: 'a-unique-identifier',
    registry: new Factory(
        factory: RateLimiterFactory::class,
        config: [
            'policy' => 'sliding_window',
            'limit' => 5,
            'interval' => '5 Minutes',
        ],
    ),
);

use Tobento\App\RateLimiter\Symfony\Registry\FixedWindow;
use Tobento\App\RateLimiter\Symfony\RateLimiterFactory;

$limiter = $limiterCreator->createFromRegistry(
    id: 'a-unique-identifier',
    registry: new FixedWindow(
        limit: 100,
        interval: '5 Minutes',
        
        // you may specify an id prefix:
        id: 'api',
        
        // you may change the storage used:
        storage: 'inmemory', // 'cache' is default
        
        // you may change the cache used if using the cache storage:
        cache: 'api-ratelimiter', // 'ratelimiter' is default
    ),
);

use Tobento\App\RateLimiter\Registry\Named;
use Tobento\App\RateLimiter\Symfony\RateLimiterFactory;

$limiter = $limiterCreator->createFromRegistry(
    id: 'a-unique-identifier',
    registry: new Named('api'),
);

use Tobento\App\RateLimiter\Symfony\Registry\NoLimit;
use Tobento\App\RateLimiter\Symfony\RateLimiterFactory;

$limiter = $limiterCreator->createFromRegistry(
    id: 'a-unique-identifier',
    registry: new NoLimit(),
);

use Tobento\App\RateLimiter\Symfony\Registry\SlidingWindow;
use Tobento\App\RateLimiter\Symfony\RateLimiterFactory;

$limiter = $limiterCreator->createFromRegistry(
    id: 'a-unique-identifier',
    registry: new SlidingWindow(
        limit: 100,
        interval: '5 Minutes',
        
        // you may specify an id prefix:
        id: 'api',
        
        // you may change the storage used:
        storage: 'inmemory', // 'cache' is default
        
        // you may change the cache used if using the cache storage:
        cache: 'api-ratelimiter', // 'ratelimiter' is default
    ),
);

use Tobento\App\RateLimiter\Symfony\Registry\TokenBucket;
use Tobento\App\RateLimiter\Symfony\RateLimiterFactory;

$limiter = $limiterCreator->createFromRegistry(
    id: 'a-unique-identifier',
    registry: new TokenBucket(
        limit: 5000,
        rateAmount: 500,
        rateInterval: '60 Minutes',
        
        // you may specify an id prefix:
        id: 'api',
        
        // you may change the storage used:
        storage: 'inmemory', // 'cache' is default
        
        // you may change the cache used if using the cache storage:
        cache: 'api-ratelimiter', // 'ratelimiter' is default
    ),
);

return [
    // ...
    'limiters' => [
        'api' => new TokenBucket(limit: 10, rateAmount: 5, rateInterval: '5 Minutes'),
        'login' => new FixedWindow(limit: 2, interval: '1 Minutes'),
    ],
];

use Tobento\App\Boot;
use Tobento\App\RateLimiter\Boot\RateLimiter;
use Tobento\App\RateLimiter\RegistriesInterface;
use Tobento\App\RateLimiter\Symfony\Registry\FixedWindow;

class RateLimitersBoot extends Boot
{
    public const BOOT = [
        // you may ensure the rate limiter boot.
        RateLimiter::class,
    ];
    
    public function boot()
    {
        // you may use the app on method to add only if requested:
        $app->on(
            RegistriesInterface::class,
            static function(RegistriesInterface $registries) {
                $registries->add(
                    name: 'api',
                    registry: new FixedWindow(limit: 2, interval: '1 Minutes'),
                );
            }
        );
    }
}
app/config/rate_limiter.php
app/config/rate_limiter.php