php-archive
| Language | PHP (7.0+) |
|---|---|
| License | MIT |
| Repository | github.com/splitbrain/php-archive |
| Documentation | API docs, README |
| Depends on | nothing; zlib extension for gzip, bz2 for bzip2 |
| Read / write | yes / yes; reads ustar, GNU long names and pax; writes ustar and GNU long names; tar, tar.gz, tar.bz2; also ZIP |
php-archive (Composer package splitbrain/php-archive, used by DokuWiki) reads and writes TAR and ZIP archives in plain PHP. It works sequentially: entries are read and written one at a time, and a new archive can be written straight to disk, so memory stays low even for large archives.
It creates new archives and reads existing ones, but doesn’t add or remove files in an existing archive. The compression is picked from the file extension (.tgz, .tar.gz, .tbz, .tar.bz2) unless you call setCompression().
Installation#
composer require splitbrain/php-archive
Basic usage: create and extract a .tar.gz#
<?php
require 'vendor/autoload.php';
use splitbrain\PHPArchive\Tar;
use splitbrain\PHPArchive\ArchiveIOException;
try {
// create: written directly to disk
$tar = new Tar();
$tar->create('backup.tar.gz'); // gzip because of the extension
$tar->addFile('docs/readme.txt', 'readme.txt'); // file on disk, name in archive
$tar->addData('VERSION', "1.2.3\n"); // file from a string
$tar->close();
// extract into "out"
$tar = new Tar();
$tar->open('backup.tar.gz');
$tar->extract('out');
} catch (ArchiveIOException $e) {
echo 'Error: ', $e->getMessage(), "\n";
}
How to list the files in a tar archive#
contents() returns an array of FileInfo objects:
<?php
require 'vendor/autoload.php';
use splitbrain\PHPArchive\Tar;
$tar = new Tar();
$tar->open('archive.tar.gz');
foreach ($tar->contents() as $info) {
printf("%s %10d %s %s\n",
$info->getIsdir() ? 'd' : '-',
$info->getSize(),
date('Y-m-d', $info->getMtime()),
$info->getPath());
}
For big archives use yieldContents(), a generator that doesn’t build the array.
How to read one file without extracting#
readCurrentEntry() reads the data of the entry the generator is on:
<?php
require 'vendor/autoload.php';
use splitbrain\PHPArchive\Tar;
$tar = new Tar();
$tar->open('archive.tar.gz');
foreach ($tar->yieldContents() as $info) {
if ($info->getPath() === 'project/README.md') {
echo $tar->readCurrentEntry();
break;
}
}
How to extract only some files#
extract($outdir, $strip, $exclude, $include) takes a number of leading path parts to strip (like tar --strip-components) and regular expressions:
<?php
$tar = new Tar();
$tar->open('wordpress.tar.gz');
// drop the top folder, extract only PHP files, skip tests
$tar->extract('site', 1, '/\/tests\//', '/\.php$/');
How to set permissions and times of added files#
Pass a FileInfo instead of a name:
<?php
require 'vendor/autoload.php';
use splitbrain\PHPArchive\Tar;
use splitbrain\PHPArchive\FileInfo;
$info = new FileInfo('bin/run.sh');
$info->setMode(0755);
$info->setMtime(1700000000);
$info->setOwner('root');
$info->setGroup('root');
$tar = new Tar();
$tar->create('release.tar.bz2'); // bzip2 because of the extension
$tar->addData($info, "#!/bin/sh\necho hi\n");
$tar->close();
Tips#
- To build an archive in memory, call
create()without a file name, add files, thengetArchive()returns the bytes orsave($file)writes them. setCompression(9, Archive::COMPRESS_GZIP)beforecreate()sets the level and type explicitly.extract()closes the archive when done; callopen()again for another pass.