Skip to content

A fast, efficient streaming library for creating ZIP files on the fly in pure userland PHP without any external tools, PHP extensions, or physical disk storage requirements.

Notifications You must be signed in to change notification settings

cubiclesoft/php-zipstreamwriter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 

Repository files navigation

ZipStreamWriter for PHP

A fast, efficient streaming library for creating ZIP files on the fly in pure userland PHP without any external tools, PHP extensions, or physical disk storage requirements. Follows version 6.3.7 of the PKWARE Zip specification. Choose from a MIT or LGPL license.

Donate Discord

If you use this project, don't forget to donate to support its development!

Features

  • Instantly start streaming a ZIP file from a PHP application to a user.
  • Extremely low memory footprint.
  • No external tools, PHP extensions (zlib is recommended though), or disk storage requirements.
  • Easily add empty directories just like ZipArchive.
  • Add files in their entirety or in chunks.
  • Automatic, intelligent Deflate compression. For whole files, if the uncompressed version is smaller than the compressed version, the uncompressed version is used.
  • Support for NTFS timestamps and UNIX timestamps + uid/gid.
  • Support for UNIX file attributes (e.g. 0644) + MS-DOS attributes.
  • Automatic Zip64 large file support.
  • Built using the PKWARE specification, a nice ZIP artifact library, a hex editor, and sheer guts and determination.
  • And much more.

Getting Started

Download/clone this repo, put the 'support' directory on a server, and then do something like this from PHP:

<?php
	require_once "support/zip_stream_writer.php";

	// Adjust various PHP settings and output relevant HTTP headers to trigger a download.
	ZipStreamWriter::StartHTTPResponse("test.zip");

	$zip = new ZipStreamWriter();
	$zip->Init();

	$lastmodified  = mktime(9, 41, 20, 12, 10, 2018);
	$lastaccessed = $lastmodified + 60;
	$created = $lastmodified - 24 * 60 * 60;

	// Register some empty directories.
	$zip->AddDirectory("dir/", array("last_modified" => $lastmodified));
	$zip->AddDirectory("dir/dir2/", array("last_modified" => $lastmodified));


	// Add smaller files with a simple call.
	$zip->AddFileFromString("dir/ Hello.txt", "Hello there!", array("last_modified" => $lastmodified));

	// Keep RAM usage low by streaming data.  Just call Read() whenever to clear out the internal buffer.
	echo $zip->Read();


	// Completely customize options per file.
	// Some combinations can break some ZIP readers though (see documentation).
	$options = array(
		"last_modified" => $lastmodified,
		"64bit" => true,
		"unix_attrs" => 0644,
		"extra_fields" => array(),
		"comment" => "Best file ever."
	);

	// NTFS timestamps.
	ZipStreamWriter::AppendNTFSExtraField($options["extra_fields"], $lastmodified, $lastaccessed, $created);

	// UNIX timestamps + uid/gid.
	$uid = 1234;
	$gid = 1234;

	ZipStreamWriter::AppendUNIXExtraField($options["extra_fields"], $lastaccessed, $lastmodified, $uid, $gid);


	// Generate and compress larger files in chunks.
	$zip->OpenFile("dir/Hello2.txt", $options);

	$zip->AppendFileData("Hello ");
	if ($zip->BytesAvailable() > 65536)  echo $zip->Read();

	$zip->AppendFileData("there!");
	echo $zip->Read();

	$zip->CloseFile();
	echo $zip->Read();

	// Finalize and close the ZIP file.  Adding a comment is optional.
	$zip->Finalize("Woot!");

	// The last Read() call is required.  The rest are optional.
	echo $zip->Read();

See the ZipStreamWriter::InitCentralDirHeader() documentation for a complete list of options.

Documentation

Limitations

The following limitations are ordered from most important to least:

  • Some tools that read ZIP files don't support Zip64 or streaming Zip64 extra fields. Any files of a declared unknown uncompressed size (uncompressed_size = -1) or specified as over 2GB without a 64-bit declaration enables Zip64 for that file.
  • Some tools that read ZIP files don't support Zip64 directory information. The ZipStreamWriter class always creates a Zip64 End of Central Directory record and locator when more than 65,535 directories/files (total) are put into a single ZIP file.
  • No encryption support, including password protection. Some parts of the specification allude to proprietary, patented technology by PKWARE, Inc.
  • Only the Store (0x0000, uncompressed) and Deflate (0x0008) compression methods are both supported and implemented.
  • Deflate compression is only available if zlib stream filter support is compiled into PHP. The class automatically falls back to the Store method if zlib stream filtering is not available or is broken. Support for Deflate compression can be verified by calling ZipStreamWriter::IsDeflateSupported().
  • Incomplete disk spanning support. The ZIP file format has the ability to span multiple disks. Even though the ZipStreamWriter class has some code that implies support for disk spanning, the implementation is incomplete and not actually usable. Not that this fact will actually matter for most people.
  • Incomplete exotic "extra fields" support. Only the most critical Zip64, NTFS, and UNIX extra fields are fully implemented. The OS/2 extra field type is also implemented - because it was easy and well-documented, not because it is actually useful. EXTRA_FIELD_WIN_NT_ACL (0x4453) support is distinctly missing. Other extra fields can be added as binary strings.
  • Limited symlink support may or may not work. The ZIP file format was originally designed for MS-DOS and FAT16. UNIX extra fields kind of support symbolic links but it's a tossup as to whether or not a reader will extract them correctly or just dump out a zero byte file to disk. NTFS supports reparse points (aka symlinks and hard links), but it is up to a ZIP file reader to create reparse points and I don't know of any that do. Symlink support is one of the major areas of the ZIP file specification that could use improvement.
  • Alternate data stream support is non-existent in the ZIP file specification even though it hints at "future support" and is therefore also not supported here.

About

A fast, efficient streaming library for creating ZIP files on the fly in pure userland PHP without any external tools, PHP extensions, or physical disk storage requirements.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages