fdpos) && $info->fdpos) { $read = $info->fdpos; fseek($fd, $info->fdpos); } if(isset($info->fdgzpos) && $info->fdgzpos) { $write = $info->fdgzpos; fseek($gzfd, $info->fdgzpos); } $fileSize = DirIteratorFile::safe_filesize($file); while(!feof($fd)) { // Call callback BEFORE the expensive gzencode operation to check execution time // This allows graceful exit before starting work that might exceed time limits if($callback) $callback($read, $fileSize); $chunk = fread($fd, $chunkSize); $bytesRead = strlen($chunk); if($bytesRead === 0) break; $compressed = gzencode($chunk, $compressionLevel); $bytesWritten = fwrite($gzfd, $compressed); $read += $bytesRead; $write += $bytesWritten; self::_putInfo($info_file, [ 'fdpos' => $read, 'fdgzpos' => $write, ]); } if(feof($fd)) { @unlink($file); @unlink($info_file); } fclose($fd); fclose($gzfd); } /** * @throws GzipException */ public static function decompress($file, ?callable $callback=null, $chunkSize=self::DEFAULT_DECOMPRESS_CHUNK_SIZE) { if(!file_exists($file) || !is_file($file)) throw new GzipException("Source file not found"); $info_file = $file . '.decompress.info'; $info = self::_getInfo($info_file); // remove .gz suffix $target = substr($file, 0, -3); $fd = fopen($target, 'a'); $gzfd = gzopen($file, 'rb'); $read = $write = 0; if(isset($info->fdpos) && $info->fdpos) { $write = $info->fdpos; fseek($fd, $info->fdpos); } if(isset($info->fdgzpos) && $info->fdgzpos) { $read = $info->fdgzpos; gzseek($gzfd, $info->fdgzpos); } $estimatedTotalSize = (int) (DirIteratorFile::safe_filesize($file) * 3); // estimating X3 compression ratio while(!gzeof($gzfd)) { // Call callback BEFORE the expensive gzread operation to check execution time if($callback) $callback('Gzip', 'Decompressing', $estimatedTotalSize, $read); $chunk = gzread($gzfd, $chunkSize); $bytesRead = strlen($chunk); if($bytesRead === 0) break; $bytesWritten = fwrite($fd, $chunk); $read += $bytesRead; $write += $bytesWritten; self::_putInfo($info_file, [ 'fdpos' => $write, 'fdgzpos' => $read, ]); } if(gzeof($gzfd)) { @unlink($file); @unlink($info_file); } fclose($fd); gzclose($gzfd); } }