PharData
| Language | PHP (5.3+, part of the Phar extension) |
|---|---|
| License | PHP License |
| Repository | github.com/php/php-src |
| Documentation | PharData on php.net |
| Depends on | Phar extension (enabled by default); zlib for gzip, bz2 for bzip2 |
| Read / write | yes / yes; ustar (no pax), tar.gz, tar.bz2; also ZIP |
PharData is the class in PHP’s Phar extension for plain tar and zip archives (the Phar class is for executable PHP archives). It works like an array of files: $tar['path/in/archive'] returns a PharFileInfo, addFile and addFromString add entries, and the object is iterable. The phar.readonly setting, which blocks writing .phar files on most servers, doesn’t apply to PharData.
Each change rewrites the archive file, and compress() writes a new compressed copy next to the original. For archives with thousands of files or many gigabytes, a streaming library like php-archive uses less memory and time.
Installation#
The Phar extension is enabled by default in PHP builds. Check with:
php -m | grep -i phar
Gzip compression needs the zlib extension, bzip2 the bz2 extension.
Basic usage: create a .tar.gz from a folder#
<?php
try {
$tar = new PharData('backup.tar');
$tar->buildFromDirectory(__DIR__ . '/docs'); // add every file under docs/
$tar->addFromString('VERSION', "1.2.3\n"); // add a file from a string
$tar->compress(Phar::GZ); // writes backup.tar.gz
unset($tar);
unlink('backup.tar'); // keep only the .tar.gz
} catch (Exception $e) {
echo 'Error: ', $e->getMessage(), "\n";
}
compress(Phar::BZ2) writes backup.tar.bz2. The second argument of compress() sets another extension, like '.tgz'.
How to extract a tar.gz#
PharData opens compressed archives directly:
<?php
try {
$tar = new PharData('archive.tar.gz');
$tar->extractTo(__DIR__ . '/out', null, true); // all files, overwrite existing
} catch (Exception $e) {
echo 'Error: ', $e->getMessage(), "\n";
}
Pass a file name or an array of names as the second argument to extract only those.
How to list the files in a tar archive#
<?php
$tar = new PharData('archive.tar.gz');
foreach (new RecursiveIteratorIterator($tar) as $file) {
// $file is a PharFileInfo; getPathname() is a phar:// URL
$name = substr($file->getPathname(), strlen('phar://' . $tar->getPath()) + 1);
printf("%10d %s %s\n", $file->getSize(), date('Y-m-d', $file->getMTime()), $name);
}
How to read one file without extracting#
<?php
$tar = new PharData('archive.tar.gz');
if (isset($tar['project/README.md'])) {
echo $tar['project/README.md']->getContent();
}
// or through the phar:// stream wrapper
$text = file_get_contents('phar://' . realpath('archive.tar.gz') . '/project/README.md');
How to add files to an existing tar#
<?php
$tar = new PharData('archive.tar');
$tar->addFile('/var/log/app.log', 'logs/app.log'); // file on disk, name in archive
$tar->addFromString('notes/hello.txt', "hello\n");
$tar->addEmptyDir('empty');
unset($tar['old/file.txt']); // delete an entry
Tips#
new PharData('x.tar')creates the file only when you add the first entry.$tar->isCompressed()returnsPhar::GZ,Phar::BZ2orfalse;decompress()writes the uncompressed.tarcopy.- PharData stores paths up to 255 bytes using the ustar
prefixfield. It ignores pax headers, so long names in archives from Python, Go or bsdtar come out cut to 100 bytes, and it fails on some GNU long-name entries. For archives made by other programs, test with your real files or use php-archive.