RateLimiter

The RateLimiter class provides a lightweight mechanism to throttle incoming requests. It uses APCu shared memory to store request counters with very low overhead, making it ideal for high-performance throttling in local and production environments.

System Requirements

APCu Extension Required

This class depends on the apcu PHP extension. If APCu is not installed and enabled correctly, the memory-based rate limiter will not work.

For XAMPP on Windows with PHP 8.2.12, do not rely only on uncommenting extension=apcu. You must first download the correct APCu DLL package that matches your PHP build exactly.

Recommended for XAMPP PHP 8.2.12

In most XAMPP Apache setups on Windows, the correct APCu package is:

APCu 5.1.23 - PHP 8.2 TS x64
Verify Before Downloading
  • PHP version must be 8.2.x
  • Architecture must match x64 or x86
  • Build must match TS or NTS
  • Do not install the wrong DLL package

Official APCu Download Links for PHP 8.2

The official PECL Windows page for APCu 5.1.23 includes direct DLL packages for PHP 8.2. This release also includes fixes specifically mentioning PHP 8.2+ behavior. :contentReference[oaicite:2]{index=2}

Recommended for XAMPP

PHP 8.2 Thread Safe (TS) x64

https://downloads.php.net/~windows/pecl/releases/apcu/5.1.23/php_apcu-5.1.23-8.2-ts-vs16-x64.zip
Download APCu 8.2 TS x64

Alternative Build

PHP 8.2 Non Thread Safe (NTS) x64

https://downloads.php.net/~windows/pecl/releases/apcu/5.1.23/php_apcu-5.1.23-8.2-nts-vs16-x64.zip
Download APCu 8.2 NTS x64

Installation Steps for XAMPP PHP 8.2.12

  1. 1. Check your current PHP build

    Open a terminal in your XAMPP PHP directory and run:

    php -v
    php -i | findstr /i "Thread Architecture Compiler"
    php -m | findstr /i apcu

    If you see Thread Safety => enabled, then the TS package is the correct one for your setup in most XAMPP Apache installations.

  2. 2. Download the correct APCu package

    For XAMPP PHP 8.2.12 on Windows, the correct package is usually:

    php_apcu-5.1.23-8.2-ts-vs16-x64.zip

    APCu 5.1.23 includes Windows packages for PHP 8.2 and includes fixes related to PHP 8.2+ serialization behavior. :contentReference[oaicite:3]{index=3}

  3. 3. Extract the ZIP file

    After downloading the package, extract the ZIP and locate the APCu DLL file inside it.

  4. 4. Copy the DLL into your XAMPP extension folder

    Copy the APCu DLL file into:

    C:\xampp\php\ext\
  5. 5. Enable APCu in php.ini

    Open your XAMPP php.ini file and add these lines if they are missing:

    extension=apcu
    apc.enabled=1
    apc.shm_size=64M
    apc.enable_cli=1

    The APCu runtime configuration is documented in the PHP manual. :contentReference[oaicite:4]{index=4}

  6. 6. Restart Apache from XAMPP

    Save php.ini, then restart Apache from the XAMPP Control Panel.

  7. 7. Verify APCu is loaded

    Run:

    php -m | findstr /i apcu
    php -i | findstr /i apc

    Or create a temporary PHP test file:

    <?php
    
    var_dump(extension_loaded('apcu'));
    var_dump(function_exists('apcu_fetch'));
    var_dump(function_exists('apcu_store'));
    var_dump(function_exists('apcu_enabled'));
    
    ?>

Common Installation Problems

Apache does not start after enabling APCu

The downloaded APCu package does not match your PHP build. Most often this is caused by choosing NTS instead of TS, or downloading x86 instead of x64.

APCu is enabled in php.ini but still not loading

Confirm the DLL file is inside C:\xampp\php\ext\ and that your selected APCu ZIP matches PHP 8.2 exactly.

APCu works in browser but not in CLI

Set apc.enable_cli=1 if you need APCu in terminal scripts. This setting is documented by the PHP manual. :contentReference[oaicite:5]{index=5}

APCu behavior on Windows

On Windows, APCu cache is per-process. This means cache sharing behavior can differ depending on how PHP is running. :contentReference[oaicite:6]{index=6}

API Reference

static check(string $key, int $maxAttempts = 60, int $seconds = 60): void

Checks if the given key has exceeded the limit. If valid, it increments the counter. If exceeded, it terminates the request immediately.

Parameters:

  • $key: Unique identifier such as user IP, user ID, or API token.
  • $maxAttempts: Number of allowed requests inside the time window.
  • $seconds: Time window in seconds.
Behavior: On failure, this method throws a Boom::tooManyRequests (HTTP 429) response and exits.

Usage Examples

1. Throttling by IP Address

Limit a user IP to 60 requests per minute. Useful for general API protection.

<?php
use PP\Security\RateLimiter;
use PP\Request;

// Identify user by IP address
$userIp = Request::$remoteAddr;

// Allow 60 requests per 60 seconds
RateLimiter::check($userIp, 60, 60);

// Continue application logic...
?>

2. Protecting Login Endpoints

Stricter limits for sensitive actions. Allow only 5 login attempts every 2 minutes.

<?php
use PP\Security\RateLimiter;
use PP\Request;

// Use a specific key prefix to separate this limit from others
$key = 'login_attempt:' . Request::$remoteAddr;

// Allow 5 attempts per 120 seconds
RateLimiter::check($key, 5, 120);

// Process login...
?>