<?php
class HTTPCache {
private $cache = [];
private $rateLimit = 10; // Requests per second
private $lastRequestTime = 0;
private $cacheDuration = 60; //Cache duration in seconds
private $proxy = null; //Optional proxy object
public function __construct($proxy = null) {
$this->proxy = $proxy;
}
/**
* Makes an HTTP request, caching the result.
*
* @param string $url The URL to request.
* @param callable $callback A callback function to execute with the response data.
* @return mixed The result of the callback function.
* @throws Exception If rate limit is exceeded.
*/
public function get($url, callable $callback) {
//Check if the request is already in the cache and within the cache duration
if ($this->isCached($url)) {
return $this->cache[$url];
}
// Apply rate limiting
$currentTime = time();
if ($currentTime - $this->lastRequestTime < 1 / $this->rateLimit) {
throw new Exception("Rate limit exceeded.");
}
$this->lastRequestTime = $currentTime;
try {
$response = $this->makeRequest($url);
if ($response) {
$this->cache[$url] = $response;
$this->cacheExpiration($url, $this->cacheDuration);
return $callback($response);
} else {
return null; //Or handle the error as needed. Can return an empty array or similar.
}
} catch (Exception $e) {
//Handle exceptions (e.g., network errors, HTTP errors)
error_log("HTTP Request Error: " . $url . " - " . $e->getMessage());
throw $e; // Re-throw the exception to be handled by the caller.
}
}
/**
* Checks if a URL is in the cache and if it's still valid.
*
* @param string $url The URL to check.
* @return bool True if the URL is in the cache and not expired, false otherwise.
*/
private function isCached(string $url): bool {
if (!isset($this->cache[$url])) {
return false;
}
$cacheEntry = $this->cache[$url];
if ($cacheEntry['expiry'] > time()) {
return true;
} else {
$this->deleteCacheEntry($url);
return false;
}
}
/**
* Makes an HTTP request. Uses cURL.
*
* @param string $url The URL to request.
* @return string|null The response body, or null on error.
* @throws Exception If the request fails.
*/
private function makeRequest(string $url): ?string {
$ch = $this->proxy ? curl_init($url) : curl_init($url);
if ($ch === false) {
throw new Exception("cURL initialization failed.");
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); //Follow redirects
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // Set a timeout
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Disable SSL verification (for testing only!)
$response = curl_exec($ch);
if ($response === false) {
$error = curl_error($ch);
throw new Exception("cURL error: " . $error);
}
curl_close($ch);
return $response;
}
/**
* Expires a cache entry.
*
* @param string $url The URL of the cached entry.
* @param int $duration The cache duration in seconds.
*/
private function cacheExpiration(string $url, int $duration): void {
$this->cache[$url]['expiry'] = time() + $duration;
}
/**
* Deletes a cache entry.
*
* @param string $url The URL of the entry to delete.
*/
private function
Add your comment