get = $get; $this->set = $set; $this->clock = $clock; } /** * Counts one hit; false when the limit for the current window is already reached. * * @param string $key Counter key. * @param int $limit Hits per window; 0 for unlimited. * @param int $window Window length in seconds. */ public function hit( string $key, int $limit, int $window ): bool { if ( $limit <= 0 ) { return true; } $now = (int) ( $this->clock )(); $stored = ( $this->get )( $key ); $start = is_array( $stored ) && isset( $stored[0], $stored[1] ) ? (int) $stored[1] : $now; $count = is_array( $stored ) && isset( $stored[0], $stored[1] ) ? (int) $stored[0] : 0; if ( $now - $start >= $window ) { $start = $now; $count = 0; } if ( $count >= $limit ) { return false; } ( $this->set )( $key, array( $count + 1, $start ), max( 1, $window - ( $now - $start ) ) ); return true; } }