PHP code example of friendsofhyperf / rate-limit

1. Go to this page and download the library: Download friendsofhyperf/rate-limit 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/ */

    

friendsofhyperf / rate-limit example snippets




namespace App\Controller;

use FriendsOfHyperf\RateLimit\Annotation\RateLimit;
use FriendsOfHyperf\RateLimit\Algorithm;

class UserController
{
    /**
     * Basic rate limiting: 60 attempts per 60 seconds
     */
    #[RateLimit(maxAttempts: 60, decay: 60)]
    public function index()
    {
        // Your code here
    }

    /**
     * Using sliding window algorithm
     */
    #[RateLimit(
        maxAttempts: 100,
        decay: 60,
        algorithm: Algorithm::SLIDING_WINDOW
    )]
    public function api()
    {
        // Your code here
    }

    /**
     * Custom key with user ID placeholder
     */
    #[RateLimit(
        key: 'user:{userId}:action',
        maxAttempts: 10,
        decay: 3600
    )]
    public function create($userId)
    {
        // Your code here
    }

    /**
     * Using array key
     */
    #[RateLimit(
        key: ['user', '{userId}', 'create'],
        maxAttempts: 5,
        decay: 60
    )]
    public function update($userId)
    {
        // Your code here
    }

    /**
     * Custom response message and code
     */
    #[RateLimit(
        maxAttempts: 5,
        decay: 60,
        response: 'Too many requests, please try again later.',
        responseCode: 429
    )]
    public function login()
    {
        // Your code here
    }

    /**
     * Using specific Redis pool
     */
    #[RateLimit(
        maxAttempts: 60,
        decay: 60,
        pool: 'rate_limit'
    )]
    public function heavyOperation()
    {
        // Your code here
    }
}



use FriendsOfHyperf\RateLimit\Annotation\RateLimit;
use FriendsOfHyperf\RateLimit\Annotation\AutoSort;

class ApiController
{
    /**
     * Multiple rate limits with smart prioritization
     * Stricter limits (smaller maxAttempts/decay ratio) are evaluated first
     */
    #[AutoSort]
    #[RateLimit(maxAttempts: 10, decay: 60)]      // 10 requests/minute - evaluated first
    #[RateLimit(maxAttempts: 100, decay: 3600)]    // 100 requests/hour - evaluated second
    public function expensiveOperation()
    {
        // Your code here
    }

    /**
     * Without AutoSort, rate limits are evaluated in declaration order
     */
    #[RateLimit(maxAttempts: 100, decay: 3600)]    // Evaluated first
    #[RateLimit(maxAttempts: 10, decay: 60)]       // Evaluated second
    public function anotherOperation()
    {
        // Your code here
    }
}

// Named placeholders
#[RateLimit(key: 'user:{userId}:{action}')]
public function action($userId, $action)

// Array format (automatically joined with ':')
#[RateLimit(key: ['user', '{userId}', '{action}'])]
public function action($userId, $action)



namespace App\Middleware;

use FriendsOfHyperf\RateLimit\Middleware\RateLimitMiddleware;
use FriendsOfHyperf\RateLimit\Algorithm;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

class ApiRateLimitMiddleware extends RateLimitMiddleware
{
    // Override default properties
    protected int $maxAttempts = 100;
    protected int $decay = 60;
    protected Algorithm $algorithm = Algorithm::SLIDING_WINDOW;
    protected string $responseMessage = 'API rate limit exceeded';
    protected int $responseCode = 429;

    // Or customize key resolution
    protected function resolveKey(ServerRequestInterface $request): string
    {
        return 'api:' . $this->getClientIp();
    }
}

// config/autoload/middlewares.php
return [
    'http' => [
        App\Middleware\ApiRateLimitMiddleware::class,
    ],
];

#[RateLimit(algorithm: Algorithm::FIXED_WINDOW)]

#[RateLimit(algorithm: Algorithm::SLIDING_WINDOW)]

#[RateLimit(algorithm: Algorithm::TOKEN_BUCKET)]

#[RateLimit(algorithm: Algorithm::LEAKY_BUCKET)]



namespace App\RateLimit;

use FriendsOfHyperf\RateLimit\Contract\RateLimiterInterface;

class CustomRateLimiter implements RateLimiterInterface
{
    public function tooManyAttempts(string $key, int $maxAttempts, int $decay): bool
    {
        // Your implementation
    }

    public function availableIn(string $key): int
    {
        // Your implementation
    }

    public function remaining(string $key, int $maxAttempts): int
    {
        // Your implementation
    }
}



try {
    $userController->index();
} catch (FriendsOfHyperf\RateLimit\Exception\RateLimitException $e) {
    // Rate limit exceeded
    $message = $e->getMessage();  // "Too Many Attempts. Please try again in X seconds."
    $code = $e->getCode();        // 429
}

// Using specific Redis pool
#[RateLimit(pool: 'rate_limit')]

return [
    'default' => [
        'host' => env('REDIS_HOST', 'localhost'),
        'port' => env('REDIS_PORT', 6379),
        'auth' => env('REDIS_AUTH', null),
        'db' => 0,
        'pool' => [
            'min_connections' => 1,
            'max_connections' => 30,
        ],
    ],
    'rate_limit' => [
        'host' => env('REDIS_HOST', 'localhost'),
        'port' => env('REDIS_PORT', 6379),
        'auth' => env('REDIS_AUTH', null),
        'db' => 1,
        'pool' => [
            'min_connections' => 5,
            'max_connections' => 50,
        ],
    ],
];

#[RateLimit(
    key: 'login:{email}',
    maxAttempts: 5,
    decay: 300, // 5 minutes
    response: 'Too many login attempts. Please try again after 5 minutes.',
    responseCode: 429
)]
public function login(string $email, string $password)
{
    // Login logic here
}

class ApiController
{
    // Public API: 100 requests per minute
    #[RateLimit(maxAttempts: 100, decay: 60)]
    public function public()
    {
        // Public endpoint
    }

    // Premium API: 1000 requests per minute
    #[RateLimit(maxAttempts: 1000, decay: 60)]
    public function premium()
    {
        // Premium endpoint
    }
}

#[RateLimit(
    key: ['user', '{userId}', 'action'],
    maxAttempts: 10,
    decay: 3600 // 1 hour
)]
public function performAction(int $userId)
{
    // Action logic here
}

class IpRateLimitMiddleware extends RateLimitMiddleware
{
    protected function resolveKey(ServerRequestInterface $request): string
    {
        return 'ip:' . $this->getClientIp();
    }
}

class ReportController
{
    /**
     * Expensive report generation with multiple protection levels
     * AutoSort ensures stricter limits are checked first for better performance
     */
    #[AutoSort]
    #[RateLimit(maxAttempts: 5, decay: 60, response: 'Too many requests. Max 5 per minute')]       // Emergency brake
    #[RateLimit(maxAttempts: 30, decay: 3600, response: 'Hourly limit exceeded. Max 30 per hour')] // Sustained load
    #[RateLimit(maxAttempts: 100, decay: 86400, response: 'Daily limit exceeded. Max 100 per day')] // Daily cap
    public function generateReport($reportType)
    {
        // Expensive report generation logic here
    }
}