1. Go to this page and download the library: Download hanfy/batch-zip-stream library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
hanfy / batch-zip-stream example snippets
use BatchZipStream\BatchZipSession;
$session = new BatchZipSession('/path/to/state', '/path/to/output.zip');
$session->startSession('my-archive');
$session->addFileFromString('hello.txt', 'Hello, World!');
$session->addFileFromString('data/config.json', '{"key": "value"}');
$session->finalize();
use BatchZipStream\BatchZipSession;
// Batch 1: Start session and add files
$session = new BatchZipSession('/path/to/state', '/path/to/output.zip');
$session->startSession('unique-session-id');
$writer = $session->getWriter();
$writer->addFileFromString('file1.txt', 'Content 1');
$session->saveProgress();
$session->close();
// ... execution ends ...
// Batch 2: Resume and add more files
$session = new BatchZipSession('/path/to/state', '/path/to/output.zip');
$session->startSession('unique-session-id'); // Resumes existing session
$writer = $session->getWriter();
$writer->addFileFromString('file2.txt', 'Content 2');
$session->saveProgress();
$session->close();
// ... execution ends ...
// Final Batch: Finalize
$session = new BatchZipSession('/path/to/state', '/path/to/output.zip');
$session->startSession('unique-session-id');
$session->finalize();
use BatchZipStream\BatchZipSession;
use BatchZipStream\Streams\FileReadableStream;
$session = new BatchZipSession('/path/to/state', '/path/to/output.zip');
$session->startSession('large-archive');
// Stream a large file (never fully loaded into memory)
$source = new FileReadableStream('/path/to/large-file.bin');
$session->addFileFromStream('large-file.bin', $source);
$session->finalize();
use BatchZipStream\BatchZipSession;
$session = new BatchZipSession('/path/to/state', '/path/to/output.zip');
$session->startSession('backup-session-12345');
// Add files (can be 1 million+ files)
foreach ($filesToBackup as $file) {
$session->addFile(
$file->getArchivePath(),
$file->getSourcePath()
);
}
// Save progress (entries are already persisted, just saves state)
$session->saveProgress();
// In the final batch, finalize
$session->finalize('Backup completed');
use BatchZipStream\BatchZipSession;
// Stream factory receives bool $append parameter
$session = BatchZipSession::withStreamFactory(
'/path/to/state',
fn(bool $append) => new S3MultipartStream('bucket', 'key', $append)
);
$session->startSession('cloud-backup');
$writer = $session->getWriter();
$writer->addFileFromString('hello.txt', 'Hello from cloud!');
$session->finalize();
use BatchZipStream\BatchZipSession;
use BatchZipStream\Streams\MemoryWritableStream;
$memory = new MemoryWritableStream();
$session = BatchZipSession::withStream('/tmp/state', $memory);
$session->startSession('memory-test');
$writer = $session->getWriter();
$writer->addFileFromString('test.txt', 'In-memory content');
$session->finalize();
// Get raw ZIP bytes
$zipBytes = $memory->getBuffer();
// Send directly over HTTP
header('Content-Type: application/zip');
header('Content-Length: ' . strlen($zipBytes));
echo $zipBytes;
use BatchZipStream\Streams\StringReadableStream;
$session = new BatchZipSession($stateDir, $archivePath);
$session->startSession('stream-input');
// From a string stream
$content = new StringReadableStream('file content', 'virtual.txt');
$session->addFileFromStream('output.txt', $content);
// From an HTTP stream (custom implementation)
$httpSource = new HttpReadableStream('https://example.com/data.json');
$session->addFileFromStream('remote/data.json', $httpSource);
$session->finalize();
new FileEntry(
filename: 'path/to/file.txt', // Path in ZIP (UTF-8, forward slashes)
crc32: 0x12345678, // CRC-32 of uncompressed data
compressedSize: 1000, // Size after compression
uncompressedSize: 2000, // Original file size
localHeaderOffset: 0, // Byte offset of local header
compressionMethod: 8, // 0=store, 8=deflate
dosTime: 0x5678ABCD, // DOS timestamp
generalPurposeBitFlag: 0x0800, // Flags (e.g., UTF-8)
versionNeeded: 0x14, // Version needed to extract
$session->startSession($sessionId); // Start or resume session
$writer = $session->getWriter(); // Get the BatchZipWriter instance
$session->addFile($path, $sourcePath, $compressionMethod, $encryptionMethod, $password); // Add file from filesystem
$session->addFileFromString($path, $content, $compressionMethod, $encryptionMethod, $password); // Add file from string
$session->addFileFromStream($path, $stream, $compressionMethod, $modificationTime); // Add file from stream
$session->addEmptyDirectory($path, $modificationTime); // Add empty directory
$session->saveProgress(); // Persist state
$session->finalize($comment); // Complete archive
$session->cleanup(); // Remove state files and close
$session->abort($reason, $deleteArchive); // Mark as failed and close
$session->getStream(); // Get output stream
$session->getState(); // Get ArchiveState instance
$session->getStats(); // Get session statistics
$session->exists($sessionId); // Check if session exists
$session->cleanupOldSessions($maxAgeSeconds); // Clean up stale sessions
$session->listSessions(); // List active session IDs
$session->close(); // Close streams/locks without deleting state
use BatchZipStream\BatchZipWriter;
use BatchZipStream\State\ArchiveState;
use BatchZipStream\State\FileEntryStore;
$state = new ArchiveState('session-id');
$entryStore = new FileEntryStore('/path/to/session.entries');
$writer = new BatchZipWriter($stream, $state, $entryStore);
$writer->addFileFromString('file.txt', 'content');
$writer->addFile('data.bin', $sourceStream);
$writer->finalize('Archive comment');
$writer->close();
new BatchZipWriter(
WritableStreamInterface $stream, // Output stream
ArchiveState $state, // Archive state
FileEntryStore $entryStore, // Entry store
int $compressionLevel = 6, // Deflate level (0-9)
int $chunkSize = 65536 // Read chunk size
);
use BatchZipStream\Persistence\FileStatePersistence;
$persistence = new FileStatePersistence('/path/to/states');
// Create session
$session = $persistence->create('session-id');
$state = $session['state'];
$entryStore = $session['entryStore'];
// Save state (tiny ~500 bytes)
$persistence->save('session-id', $state);
// Load session
$session = $persistence->load('session-id');
// Clean up all session files
$persistence->delete('session-id');
class RedisStatePersistence implements StatePersistenceInterface
{
public function create(string $sessionId): array
{
$state = new ArchiveState($sessionId);
$entryStore = new FileEntryStore($this->getEntryPath($sessionId));
$entryStore->open(true);
return ['state' => $state, 'entryStore' => $entryStore];
}
public function load(string $sessionId): ?array
{
$json = $this->redis->get("zip:state:$sessionId");
if ($json === null) return null;
$state = ArchiveState::fromJson($json);
$entryStore = new FileEntryStore($this->getEntryPath($sessionId));
$entryStore->open(false);
return ['state' => $state, 'entryStore' => $entryStore];
}
public function save(string $sessionId, ArchiveState $state): void
{
$this->redis->set("zip:state:$sessionId", $state->toJson());
}
// ... other methods
}
$session = new BatchZipSession($stateDir, $archivePath);
$session->startSession('large-archive');
// Add many files
for ($i = 0; $i < 70000; $i++) {
$session->addFileFromString("file-$i.txt", "content");
}
// ZIP64 is automatically enabled
$state = $session->getState();
assert($state->
use BatchZipStream\BatchZipSession;
use BatchZipStream\Core\ZipFormat;
$globalPassword = 'my-global-secret';
$session = new BatchZipSession(
$stateDir,
$archivePath,
6, // Compression level
65536, // Chunk size
null, // Custom state persistence
$globalPassword
);
$session->startSession('encrypted-archive');
// 1. Encrypt with WinZip AES-256 (recommended) using the global password
$session->addFileFromString(
'secret.txt',
'Top Secret Content',
ZipFormat::COMPRESSION_DEFLATE,
ZipFormat::ENC_AES_256
);
// 2. Encrypt with Traditional PKWARE encryption using the global password
$session->addFile(
'legacy.txt',
'/path/to/local-file.txt',
ZipFormat::COMPRESSION_DEFLATE,
ZipFormat::ENC_TRADITIONAL
);
// 3. Keep a file public (unencrypted) in the same archive
$session->addFileFromString(
'public.txt',
'This is readable by anyone',
ZipFormat::COMPRESSION_DEFLATE,
ZipFormat::ENC_NONE
);
$session->finalize();
// Encrypt using traditional PKWARE with a custom password instead of the global one
$session->addFileFromString(
'override.txt',
'Custom Password Protected Content',
ZipFormat::COMPRESSION_DEFLATE,
ZipFormat::ENC_TRADITIONAL,
'file-specific-password'
);
// When using the writer directly:
$writer = $session->getWriter();
$writer->addFileFromString(
'custom-aes.txt',
'AES-256 with custom password',
ZipFormat::COMPRESSION_DEFLATE,
null, // modificationTime
ZipFormat::ENC_AES_256,
'custom-aes-password'
);
class S3MultipartStream implements WritableStreamInterface
{
public function write(string $data): int
{
// Buffer and upload parts
$this->buffer .= $data;
if (strlen($this->buffer) >= 5 * 1024 * 1024) {
$this->uploadPart($this->buffer);
$this->buffer = '';
}
return strlen($data);
}
public function close(): void
{
if ($this->buffer !== '') {
$this->uploadPart($this->buffer);
}
$this->completeMultipartUpload();
}
}
use BatchZipStream\Streams\MemoryWritableStream;
$memory = new MemoryWritableStream();
$session = BatchZipSession::withStream('/state', $memory);
$session->startSession('test');
$session->addFileFromString('test.txt', 'Hello!');
$session->finalize();
// Access the buffer
$zipBytes = $memory->getBuffer(); // Raw ZIP bytes
$length = $memory->getLength(); // Total bytes written
// Reset for reuse
$memory->reset();
use BatchZipStream\Streams\FileWritableStream;
$stream = new FileWritableStream('/path/to/archive.zip');
$stream->write($data);
$stream->flush();
$stream->close();
use BatchZipStream\Streams\BufferedWritableStream;
$buffered = new BufferedWritableStream($innerStream, 65536);
use BatchZipStream\Streams\CallbackWritableStream;
$stream = new CallbackWritableStream(function(string $data) use ($s3) {
$s3->appendToObject($data);
return strlen($data);
});
class HttpReadableStream implements ReadableStreamInterface
{
public function __construct(string $url)
{
$this->stream = fopen($url, 'rb');
}
public function read(int $length): string
{
return fread($this->stream, $length);
}
public function eof(): bool
{
return feof($this->stream);
}
}