Rate Limit Gate
Tracks request attempts by key and determines whether a request should be allowed or delayed.
Function signature
ogRateLimitGate(attempts, max_attempts = 5, window_seconds = 300, current_time = 0)
Categories
- Security
Parameters
attemptsPrior Unix timestamps for this identity key.max_attemptsMaximum attempts inside the window.window_secondsWindow size in seconds.current_timeOptional current Unix timestamp.Return value
Short public-safe status message.
- allowed
- retry_after
- recent_attempts
- attempt_count
- max_attempts
- window_seconds
Compatibility
Existing function name and call order preserved; metadata signature corrected to source.
Minimum PHP version: 7.4
Security notes
Validate request method, identity, permissions, and caller-owned allowlists before use; keep secrets out of public output.
Code
<?php
/*
* Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
* Free for personal and internal use. Paid project use requires visible credit
* to Jeffery L. Paris. Corporate use requires a paid license fee unless a
* separate written license states otherwise.
*/
/**
* Evaluates whether a request should pass a fixed-window rate limit.
*
* The caller owns persistence. Pass recent attempt timestamps for the identity
* key being checked, then store the returned attempts array after recording a
* denied or accepted attempt according to the controller policy.
*
* @param array $attempts Prior Unix timestamps for this identity key.
* @param int $max_attempts Maximum attempts inside the window.
* @param int $window_seconds Window size in seconds.
* @param int $current_time Optional current Unix timestamp.
* @return array Rate-limit decision and retained attempt timestamps.
*/
function ogRateLimitGate($attempts, $max_attempts = 5, $window_seconds = 300, $current_time = 0) {
$result = array(
'success' => false,
'message' => '',
'data' => array()
);
if (!is_array($attempts)) {
$attempts = array();
}
$max_attempts = (int)$max_attempts;
$window_seconds = (int)$window_seconds;
$current_time = (int)$current_time;
if ($current_time <= 0) {
$current_time = time();
}
if ($max_attempts < 1) {
$max_attempts = 1;
}
if ($window_seconds < 60) {
$window_seconds = 60;
}
$recent_attempts = array();
foreach ($attempts as $attempt_time) {
$attempt_time = (int)$attempt_time;
if ($attempt_time >= ($current_time - $window_seconds) && $attempt_time <= $current_time) {
$recent_attempts[] = $attempt_time;
}
}
sort($recent_attempts);
$allowed = true;
$retry_after = 0;
if (count($recent_attempts) >= $max_attempts) {
$allowed = false;
$oldest = reset($recent_attempts);
$retry_after = ($oldest + $window_seconds) - $current_time;
if ($retry_after < 0) {
$retry_after = 0;
}
}
$result['success'] = true;
$result['message'] = 'Rate limit evaluated.';
$result['data'] = array(
'allowed' => $allowed,
'retry_after' => $retry_after,
'recent_attempts' => $recent_attempts,
'attempt_count' => count($recent_attempts),
'max_attempts' => $max_attempts,
'window_seconds' => $window_seconds
);
return $result;
}