redis = $redis; } public function getCachedFile(string $url): ?string { $cacheKey = $this->cachePrefix . md5($url); $result = $this->redis->get($cacheKey); return $result === false ? null : $result; } public function cacheFile(string $url, string $content): void { $cacheKey = $this->cachePrefix . md5($url); $this->redis->setex($cacheKey, $this->cacheExpire, $content); } public function downloadWithProgress(string $url, callable $progressCallback = null): string|false { $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 120, CURLOPT_CONNECTTIMEOUT => 30, CURLOPT_FOLLOWLOCATION => true, CURLOPT_MAXREDIRS => 5, CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_ENCODING => '', CURLOPT_NOPROGRESS => false, CURLOPT_PROGRESSFUNCTION => $progressCallback ]); $content = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($content === false || $httpCode !== 200) { return false; } return $content; } }