Skip to content

ZipStream

Streamed, dynamically generated zip archives.

Usage

Streaming zip archives is a simple, three-step process:

  1. Create the zip stream:
$zip = new ZipStream(outputName: 'example.zip');
  1. Add one or more files to the archive:
// add first file
$zip->addFile(fileName: 'world.txt', data: 'Hello World');

// add second file
$zip->addFile(fileName: 'moon.txt', data: 'Hello Moon');
  1. Finish the zip stream:
$zip->finish();

You can also add an archive comment, add comments to individual files, and adjust the timestamp of files. See the API documentation for each method below for additional information.

Example

// create a new zip stream object
$zip = new ZipStream(outputName: 'some_files.zip');

// list of local files
$files = array('foo.txt', 'bar.jpg');

// read and add each file to the archive
foreach ($files as $path)
  $zip->addFileFromPath(fileName: $path, $path);

// write archive footer to stream
$zip->finish();
  • Full name: \ZipStream\ZipStream

Properties

ready

private bool $ready

offset

private int $offset

centralDirectoryRecords

private string[] $centralDirectoryRecords

outputStream

private resource $outputStream

httpHeaderCallback

private \Closure $httpHeaderCallback

recordedSimulation

private \ZipStream\File[] $recordedSimulation

operationMode

private \ZipStream\OperationMode $operationMode

comment

private string $comment

defaultCompressionMethod

private \ZipStream\CompressionMethod $defaultCompressionMethod

defaultDeflateLevel

private int $defaultDeflateLevel

enableZip64

private bool $enableZip64

defaultEnableZeroHeader

private bool $defaultEnableZeroHeader

sendHttpHeaders

private bool $sendHttpHeaders

outputName

private ?string $outputName

contentDisposition

private string $contentDisposition

contentType

private string $contentType

flushOutput

private bool $flushOutput

Methods

__construct

Create a new ZipStream object.

public __construct(\ZipStream\OperationMode $operationMode = OperationMode::NORMAL, string $comment = '', \Psr\Http\Message\StreamInterface|resource|null $outputStream = null, \ZipStream\CompressionMethod $defaultCompressionMethod = CompressionMethod::DEFLATE, int $defaultDeflateLevel = 6, bool $enableZip64 = true, bool $defaultEnableZeroHeader = true, bool $sendHttpHeaders = true, ?\Closure $httpHeaderCallback = null, string|null $outputName = null, string $contentDisposition = 'attachment', string $contentType = 'application/x-zip', bool $flushOutput = false): self
Examples
// create a new zip file named 'foo.zip'
$zip = new ZipStream(outputName: 'foo.zip');

// create a new zip file named 'bar.zip' with a comment
$zip = new ZipStream(
  outputName: 'bar.zip',
  comment: 'this is a comment for the zip file.',
);

Parameters:

Parameter Type Description
$operationMode \ZipStream\OperationMode
The mode can be used to switch between NORMAL and SIMULATION_* modes.
For details see the OperationMode documentation.

Default to NORMAL.
$comment string
Archive Level Comment
$outputStream \Psr\Http\Message\StreamInterface|resource|null
Override the output of the archive to a different target.

By default the archive is sent to STDOUT.
$defaultCompressionMethod \ZipStream\CompressionMethod
How to handle file compression. Legal values are
CompressionMethod::DEFLATE (the default), or
CompressionMethod::STORE. STORE sends the file raw and is
significantly faster, while DEFLATE compresses the file and
is much, much slower.
$defaultDeflateLevel int
Default deflation level. Only relevant if compressionMethod
is DEFLATE.

See details of deflate_init
$enableZip64 bool
Enable Zip64 extension, supporting very large
archives (any size > 4 GB or file count > 64k)
$defaultEnableZeroHeader bool
Enable streaming files with single read.

When the zero header is set, the file is streamed into the output
and the size & checksum are added at the end of the file. This is the
fastest method and uses the least memory. Unfortunately not all
ZIP clients fully support this and can lead to clients reporting
the generated ZIP files as corrupted in combination with other
circumstances. (Zip64 enabled, using UTF8 in comments / names etc.)

When the zero header is not set, the length & checksum need to be
defined before the file is actually added. To prevent loading all
the data into memory, the data has to be read twice. If the data
which is added is not seekable, this call will fail.
$sendHttpHeaders bool
Boolean indicating whether or not to send
the HTTP headers for this file.
$httpHeaderCallback ?\Closure
The method called to send HTTP headers
$outputName string|null
The name of the created archive.

Only relevant if $sendHttpHeaders = true.
$contentDisposition string
HTTP Content-Disposition

Only relevant if sendHttpHeaders = true.
$contentType string
HTTP Content Type

Only relevant if sendHttpHeaders = true.
$flushOutput bool
Enable flush after every write to output stream.

addFile

Add a file to the archive.

public addFile(string $fileName, string $data, string $comment = '', ?\ZipStream\CompressionMethod $compressionMethod = null, ?int $deflateLevel = null, ?\DateTimeInterface $lastModificationDateTime = null, ?int $maxSize = null, ?int $exactSize = null, ?bool $enableZeroHeader = null): void
File Options

See {@see \ZipStream\addFileFromPsr7Stream()}

Examples
// add a file named 'world.txt'
$zip->addFile(fileName: 'world.txt', data: 'Hello World!');

// add a file named 'bar.jpg' with a comment and a last-modified
// time of two hours ago
$zip->addFile(
  fileName: 'bar.jpg',
  data: $data,
  comment: 'this is a comment about bar.jpg',
  lastModificationDateTime: new DateTime('2 hours ago'),
);

Parameters:

Parameter Type Description
$fileName string
$data string

contents of file
$comment string
$compressionMethod ?\ZipStream\CompressionMethod
$deflateLevel ?int
$lastModificationDateTime ?\DateTimeInterface
$maxSize ?int
$exactSize ?int
$enableZeroHeader ?bool

addFileFromPath

Add a file at path to the archive.

public addFileFromPath(string $fileName, string $path, string $comment = '', ?\ZipStream\CompressionMethod $compressionMethod = null, ?int $deflateLevel = null, ?\DateTimeInterface $lastModificationDateTime = null, ?int $maxSize = null, ?int $exactSize = null, ?bool $enableZeroHeader = null): void
File Options

See {@see \ZipStream\addFileFromPsr7Stream()}

Examples
// add a file named 'foo.txt' from the local file '/tmp/foo.txt'
$zip->addFileFromPath(
  fileName: 'foo.txt',
  path: '/tmp/foo.txt',
);

// add a file named 'bigfile.rar' from the local file
// '/usr/share/bigfile.rar' with a comment and a last-modified
// time of two hours ago
$zip->addFileFromPath(
  fileName: 'bigfile.rar',
  path: '/usr/share/bigfile.rar',
  comment: 'this is a comment about bigfile.rar',
  lastModificationDateTime: new DateTime('2 hours ago'),
);

Parameters:

Parameter Type Description
$fileName string
$path string
$comment string
$compressionMethod ?\ZipStream\CompressionMethod
$deflateLevel ?int
$lastModificationDateTime ?\DateTimeInterface
$maxSize ?int
$exactSize ?int
$enableZeroHeader ?bool

Throws:


addFileFromStream

Add an open stream (resource) to the archive.

public addFileFromStream(string $fileName, resource $stream, string $comment = '', ?\ZipStream\CompressionMethod $compressionMethod = null, ?int $deflateLevel = null, ?\DateTimeInterface $lastModificationDateTime = null, ?int $maxSize = null, ?int $exactSize = null, ?bool $enableZeroHeader = null): void
File Options

See {@see \ZipStream\addFileFromPsr7Stream()}

Examples
// create a temporary file stream and write text to it
$filePointer = tmpfile();
fwrite($filePointer, 'The quick brown fox jumped over the lazy dog.');

// add a file named 'streamfile.txt' from the content of the stream
$archive->addFileFromStream(
  fileName: 'streamfile.txt',
  stream: $filePointer,
);

Parameters:

Parameter Type Description
$fileName string
$stream resource contents of file as a stream resource
$comment string
$compressionMethod ?\ZipStream\CompressionMethod
$deflateLevel ?int
$lastModificationDateTime ?\DateTimeInterface
$maxSize ?int
$exactSize ?int
$enableZeroHeader ?bool

addFileFromPsr7Stream

Add an open stream to the archive.

public addFileFromPsr7Stream(string $fileName, \Psr\Http\Message\StreamInterface $stream, string $comment = '', ?\ZipStream\CompressionMethod $compressionMethod = null, ?int $deflateLevel = null, ?\DateTimeInterface $lastModificationDateTime = null, ?int $maxSize = null, ?int $exactSize = null, ?bool $enableZeroHeader = null): void
Examples
$stream = $response->getBody();
// add a file named 'streamfile.txt' from the content of the stream
$archive->addFileFromPsr7Stream(
  fileName: 'streamfile.txt',
  stream: $stream,
);

Parameters:

Parameter Type Description
$fileName string
path of file in archive (including directory)
$stream \Psr\Http\Message\StreamInterface
contents of file as a stream resource
$comment string
ZIP comment for this file
$compressionMethod ?\ZipStream\CompressionMethod
Override defaultCompressionMethod

See {@see \ZipStream__construct()}
$deflateLevel ?int
Override defaultDeflateLevel

See {@see \ZipStream__construct()}
$lastModificationDateTime ?\DateTimeInterface
Set last modification time of file.

Default: now
$maxSize ?int
Only read maxSize bytes from file.

The file is considered done when either reaching EOF
or the maxSize.
$exactSize ?int
Read exactly exactSize bytes from file.
If EOF is reached before reading exactSize bytes, an error will be
thrown. The parameter allows for faster size calculations if the stream
does not support fstat size or is slow and otherwise known beforehand.
$enableZeroHeader ?bool
Override defaultEnableZeroHeader

See {@see \ZipStream__construct()}

addFileFromCallback

Add a file based on a callback.

public addFileFromCallback(string $fileName, \Closure $callback, string $comment = '', ?\ZipStream\CompressionMethod $compressionMethod = null, ?int $deflateLevel = null, ?\DateTimeInterface $lastModificationDateTime = null, ?int $maxSize = null, ?int $exactSize = null, ?bool $enableZeroHeader = null): void

This is useful when you want to simulate a lot of files without keeping all of the file handles open at the same time.

Examples
foreach($files as $name => $size) {
  $archive->addFileFromCallback(
    fileName: 'streamfile.txt',
    exactSize: $size,
    callback: function() use($name): Psr\Http\Message\StreamInterface {
      $response = download($name);
      return $response->getBody();
    }
  );
}

Parameters:

Parameter Type Description
$fileName string
path of file in archive (including directory)
$callback \Closure
$comment string
ZIP comment for this file
$compressionMethod ?\ZipStream\CompressionMethod
Override defaultCompressionMethod

See {@see \ZipStream__construct()}
$deflateLevel ?int
Override defaultDeflateLevel

See {@see \ZipStream__construct()}
$lastModificationDateTime ?\DateTimeInterface
Set last modification time of file.

Default: now
$maxSize ?int
Only read maxSize bytes from file.

The file is considered done when either reaching EOF
or the maxSize.
$exactSize ?int
Read exactly exactSize bytes from file.
If EOF is reached before reading exactSize bytes, an error will be
thrown. The parameter allows for faster size calculations if the stream
does not support fstat size or is slow and otherwise known beforehand.
$enableZeroHeader ?bool
Override defaultEnableZeroHeader

See {@see \ZipStream__construct()}

addDirectory

Add a directory to the archive.

public addDirectory(string $fileName, string $comment = '', ?\DateTimeInterface $lastModificationDateTime = null): void
File Options

See {@see \ZipStream\addFileFromPsr7Stream()}

Examples
// add a directory named 'world/'
$zip->addDirectory(fileName: 'world/');

Parameters:

Parameter Type Description
$fileName string
$comment string
$lastModificationDateTime ?\DateTimeInterface

executeSimulation

Executes a previously calculated simulation.

public executeSimulation(): void
Example
$zip = new ZipStream(
  outputName: 'foo.zip',
  operationMode: OperationMode::SIMULATE_STRICT,
);

$zip->addFile('test.txt', 'Hello World');

$size = $zip->finish();

header('Content-Length: '. $size);

$zip->executeSimulation();

finish

Write zip footer to stream.

public finish(): int

The clase is left in an unusable state after finish.

Example
// write footer to stream
$zip->finish();

normalizeStream

private static normalizeStream(\Psr\Http\Message\StreamInterface|resource|null $outputStream): resource
  • This method is static.

Parameters:

Parameter Type Description
$outputStream \Psr\Http\Message\StreamInterface|resource|null

recordSentBytes

Record sent bytes

private recordSentBytes(int $sentBytes): void

Parameters:

Parameter Type Description
$sentBytes int

send

Send string, sending HTTP headers if necessary.

private send(string $data): void

Flush output after write if configure option is set.

Parameters:

Parameter Type Description
$data string

sendHttpHeaders

Send HTTP headers for this stream.

private sendHttpHeaders(): void

clear

Clear all internal variables. Note that the stream object is not usable after this.

private clear(): void


Automatically generated on 2025-03-18