NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Packagist · #3231 most downloaded on Packagist
UnifiedArchive - an archive manager with unified interface of working with all popular archive formats (zip/7z/rar/gz/bz2/xz/cab/tar/tar.gz/tar.bz2/tar.x/tar.Z/...) for PHP with ability for listing, reading, extracting and creation + built-in console archive manager.
Last release 1 years ago
25 Aug 2025
Ships unpredictably
gaps range from 2 weeks to 2.0 years
Nearly every release is documented
notes for 33 of 33 stable releases
Nothing withdrawn
no release was ever pulled
12 years old
34 releases · first in 2014
Fix php 8.5 deprecation ( @cedric-anne )
Fix php 8.5 deprecation (@cedric-anne)
Release for php 8.4 without deprecated-issues ( #47 by @cedric-anne , #51 )
Release for php 8.4 without deprecated-issues (#47 by @cedric-anne, #51)
One column per quarter.
BC change: Increased minimal PHP version to 7.1.0! (#47)
Specified supported php versions : 5.5.0-8.3.x, deprecations in 8.4.x ( #47 by @cedric-anne )
xz in matrix: SevenZip does not support it (#45 by @rotdrop)Formats::checkFormatSupportAbility() marked deprecated, use can() instead.
can() instead.add() instead.fileOrFiles handling: if passed string, then file/directory will be archived with full its original name (as opposed to relative name before).test() functionality - returns list of mismatched hashes.Fixed invalid initialization of TarByPear driver (from 1.1.8)
TarByPear driver (from 1.1.8)Fixed detection of archive format by it's content
Fixed detection of archive format by it's content
Old methods are marked as deprecated and will be deleted in future releases.
Fixed:
UnifiedArchive->getComment() now returns null when comment is not supported by driver (#39)UnifiedArchive->getFileData()->modificationTime is integer timestamp now in case of NelexaZip driver instead of DateTimeImmutable (#38)PharData::create for zip-archivesDeprecations:
UnifiedArchive:
getFileNames => getFilesextractFiles => extractaddFiles => adddeleteFiles => deletearchiveFiles => archivecanOpenArchive => canOpenUnifiedArchive::detectArchiveType - use Formats::detectArchiveFormat insteadUnifiedArchive::archiveDirectory/archiveFile - use UnifiedArchive::archive insteadUnifiedArchive::canCreateType - Formats::canCreateNew functions:
Formats::getFormatExtension($archiveFormat)UnifiedArchive->prepareForArchiving($fileOrFiles, $archiveName = null)UnifiedArchive::createInString() and BasicDriver::CREATE_IN_STRING ability constantFixed:
UnifiedArchive->getComment() now returns null when comment is not supported by driver (#39)UnifiedArchive->getFileData()->modificationTime is integer timestamp now in case of NelexaZip driver instead of DateTimeImmutable (#38)PharData::create for zip-archivesDeprecations:
UnifiedArchive:
getFileNames => getFilesextractFiles => extractaddFiles => adddeleteFiles => deletearchiveFiles => archivecanOpenArchive => canOpenUnifiedArchive::detectArchiveType - use Formats::detectArchiveFormat insteadUnifiedArchive::archiveDirectory/archiveFile - use UnifiedArchive::archive insteadUnifiedArchive::canCreateType - Formats::canCreateNew functions:
Formats::getFormatExtension($archiveFormat)UnifiedArchive->prepareForArchiving($fileOrFiles, $archiveName = null)UnifiedArchive::createInString() and BasicDriver::CREATE_IN_STRING ability constantopen does not throw an Exception, it returns null
open does not throw an Exception, it returns nullcanOpenArchive, canOpenType, canCreateType, getArchiveType, detectArchiveType, getFileResource, getArchiveFormat, isFileExists, getArchiveSize, countCompressedFilesSize, countUncompressedFilesSize.Changed signature: UnifiedArchive::open($filename, string|null $password = null) => UnifiedArchive::open($filename, array $abilities = [], string|null
BC-breaking changes:
Changed signature: UnifiedArchive::open($filename, string|null $password = null) => UnifiedArchive::open($filename, array $abilities = [], string|null $password = null). Right now if second argument is string, it will be treated as password (for BC-compatability).
open throws an Exception when format is not recognized or there's no driver that support requested abilities.
addFiles/deleteFiles/getComment/setComment throws an Exception when driver does not support this ability.
Deleted methods in UnifiedArchive: canOpenArchive, canOpenType, canCreateType, getArchiveType, detectArchiveType, getFileResource, getArchiveFormat, isFileExists, getArchiveSize, countCompressedFilesSize, countUncompressedFilesSize.
New features:
use \wapmorgan\UnifiedArchive\Drivers\BasicDriver;
# opens an array with driver, that supports content streaming and appending
$archive = \wapmorgan\UnifiedArchive\UnifiedArchive::open('archive.7z', [BasicDriver::STREAM_CONTENT, BasicDriver::APPEND]);
# if not specified, uses OPEN or OPEN_ENCRYPTED check, if password passedUnifiedArchive::test($files = []) (and cam files:test command) to test archive contents (compare actual control sum with stored crc32).system:drivers, system:formats, system:format, added command files:test.Driver changes:
NelexaZip pure-PHP driver.Iso driver extraction ability.SevenZip driver (via descript.ion file in archive).Reimplemented cam (console utility) - now it's on symfony/console and supports all features and more functions (folders, types) of UA.
New features:
cam (console utility) - now it's on symfony/console and supports all features and more functions (folders, types) of UA../vendor/bin/cam system:drivers) of specific drivers: AlchemyZippy, Cab, Iso, Lzma, Rar, SevenZip, TarByPear.?callable $fileProgressCallable of UnifiedArchive::archiveFiles().addFiles()/archiveFiles())
[
'' => ['./folder1', './folder2'],
'README.md' => './subfolder/README.md'
] # Archive will have all folder1, folder2 contents in the root and README.mdFixed:
extract() and listContent() and their result of PclZip interface (UnifiedArchive::getPclZipInterface()) to correspond to original library (object => array).Format changes:
TarByPear, TarByPhar, Zip.TarByPhar.Disabled rar for SevenZip driver.
Disabled rar for SevenZip driver.
Methods renamed (old exist, but marked as deprecated):
Changed format of $files in archiveFiles() and addFiles()
[
'/var/www/log.txt', // will be "/var/www/log.txt"
'log2.txt' => '/var/www/log2.txt', // will be "/log2.txt"
'/var/www/site', // will be "/var/www/site"
'site2' => '/var/www/site2', // will be "/site2"
]
Old format also works, but there can be a bad case. If you have /var/www/log2.txt and log2.txt (in current directory) and pass following:
[
'/var/www/log2.txt' => 'log2.txt',
]
it will archive log2.txt as /var/www/log2.txt in an archive (new behaviour).
New features:
Formats::canStream() to check if an archive files can be streamed.Zip, SevenZip) and 7z (SevenZip)) - added nullable $password argument to:
UnifiedArchive::archiveFiles($fileOrFiles, $archiveName, $compressionLevel = BasicDriver::COMPRESSION_AVERAGE, $password = null)UnifiedArchive::archiveFile($file, $archiveName, $compressionLevel = BasicDriver::COMPRESSION_AVERAGE, $password = null)UnifiedArchive::archiveDirectory($directory, $archiveName, $compressionLevel = BasicDriver::COMPRESSION_AVERAGE, $password = null)UnifiedArchive->getMimeType() to get mime type of archive.UnifiedArchive->getComment() to get comment of an archive. Available only in Zip and Rar drivers, others return null.UnifiedArchive->setComment(?string $comment) to set comment. Available only in Zip.UnifiedArcihve->getFileNames(). If works as fnmatch() does.$a = \wapmorgan\UnifiedArchive\UnifiedArchive::open('tests/archives/fixtures.7z');
foreach ($a as $file => $data) {
echo $file.PHP_EOL;
}
$file_data = $a['filename'];
Fixed:
SevenZip driver: disabled tar.gz, tar.bzip2 support as it isn't supported properly and described which formats driver can create, append, modify and encrypt.Methods renamed (old exist, but marked as deprecated):
UnifiedArchive->getArchiveFormat -> UnifiedArchive->getFormat.UnifiedArchive->getArchiveSize -> UnifiedArchive->getSize.UnifiedArchive->countCompressedFilesSize -> UnifiedArchive->getCompressedSize.UnifiedArchive->countUncompressedFilesSize -> UnifiedArchive->getOriginalSize.UnifiedArchive->getFileResource -> UnifiedArchive->getFileStream.UnifiedArchive->isFileExists -> UnifiedArchive->hasFile.Fixed calculation of tar's uncompressed size opened via TarByPear driver. Fixed working with *tar.xz* archives.
Fixed calculation of tar's uncompressed size opened via TarByPear driver.
Fixed working with tar.xz archives.
Cleaned package.
Cleaned package.
Old methods exist, but marked as deprecated.
New features:
$password argument to UnifiedArchive::open($fileName, $password = null). Works only with: zip, rar, 7z.$compressionLevel argument (with default BasicDriver::COMPRESSION_AVERAGE level) to:
UnifiedArchive::archiveFiles($fileOrFiles, $archiveName, $compressionLevel = BasicDriver::COMPRESSION_AVERAGE)UnifiedArchive::archiveFile($file, $archiveName, $compressionLevel = BasicDriver::COMPRESSION_AVERAGE)UnifiedArchive::archiveDirectory($file, $archiveName, $compressionLevel = BasicDriver::COMPRESSION_AVERAGE)
Works only with: zip, gzip.addFileFromString method:
UnifiedArchive->addFileFromString(string $inArchiveName, string $content).Formats::canOpen()Formats::canCreate()Formats::canAppend() - check if file can be added to an archiveFormats::canUpdate() - check if archive member can be removedFormats::canEncrypt() - check if encrypted archive can be openedFormat changes:
Methods renamed:
UnifiedArchive::canOpenType -> Formats::canOpenUnifiedArchive::canOpenArchive -> UnifiedArchive::canOpenUnifiedArchive::canCreateType -> Formats::canCreateUnifiedArchive->getArchiveType -> UnifiedArchive->getArchiveFormatImproved extendable for all classes - used late-static binding everywhere.
Format specific:
Fixed automatic opening of .tar.Z and .tar.xz.
Format specific:
Deleted deprecated UnifiedArchive methods: extractNode, archiveNodes.
BC-breaking changes:
extractNode, archiveNodes.archiveFiles() to prepareForArchiving().getFileData, getFileContent, getFileResource throws NonExistentArchiveFileException when file is not present in archive.extractFiles throws:
EmptyFileListExceptionArchiveExtractionExceptiondeleteFiles, addFiles, addFile and addDirectory throws:
EmptyFileListExceptionUnsupportedOperationExceptionArchiveModificationExceptionarchiveFiles, archiveFile and archiveDirectory throws:
FileAlreadyExistsExceptionEmptyFileListExceptionUnsupportedOperationExceptionArchiveCreationException7zip: Fixed 7z-archiving, when archiving files should be renamed in archive
BC-breaking changes:
Format specific:
New features:
canCreateType(): boolcanAddFiles(): boolcanDeleteFiles(): boolPclZip-interface getter renamed to getPclZipInterface().
BC-breaking changes:
getPclZipInterface().addFiles() return number of added files instead of total files number.Other changes:
addFiles() / deleteFiles() / archiveFiles() throw \Exceptions when any error occurred (and even when
files list is empty)./ always as directory separator in addFiles() and archiveFiles().Format-specific changes:
getFileNames()).addFiles() usage.archiveFiles() usage.TarArchive adapter):
addFiles().deleteFiles() usage.canOpenArchive() and canOpenType().PharData adapter):
addFiles()/deleteFiles() usage and path generation of archive in archiveFiles().getFileNames() to use UNIX path separator ("/").getFileNames()).deleteFiles() and archiveFiles() in-archive paths.getFileData().7z system call (useful for big archives).extractFiles() functionality.Changed algorithm of files list generation in `archiveFiles()` and `addFiles()`: `php // 1. one file $archive->archiveFiles('/var/www/site/abc.log', '
API changes:
Changed algorithm of files list generation in archiveFiles() and addFiles():
// 1. one file
$archive->archiveFiles('/var/www/site/abc.log', 'archive.zip'); // => stored as 'abc.log'
// 2. directory
$archive->archiveFiles('/var/www/site/runtime/logs', 'archive.zip'); // => directory content stored in archive root
// 3. list
$archive->archiveFiles([
'/var/www/site/abc.log' => 'abc.log', // stored as 'abc.log'
'/var/www/site/abc.log', // stored as '/var/www/site/abc.log'
'/var/www/site/runtime/logs' => 'logs', // directory content stored in 'logs' dir
'/var/www/site/runtime/logs', // stored as '/var/www/site/runtime/logs'
], 'archive.zip');
Disabled paths expanding in extractFiles() and deleteFiles() by default.
If you need to expand src/ path to all files within this directory in archive, set second argument $expandFilesList argument to true.
$archive->extractFiles(__DIR__, 'src/', true);
$archive->deleteFiles('tests/', true);
Added new element in archiveFiles() result in emulation mode. Now it returns an archive with 4 elements: new type element with archive type.
Fixes:
getFileContent($file) (before it didn't work).getFileContent($file) for RAR archives by using streams (before it did extract file in temporarily folder, read it and then delete it).Improvements:
isFileExists($file): bool method for checking if archive has a file with specific name.getFileResource($file): resource method for getting a file descriptor for reading all file content without full extraction in memory.canOpenArchive($archiveFileName): bool and canOpenType($archiveFormat): bool static methods to check if specific archive or format can be opened.detectArchiveType($fileName): string|false static method to detect (by filename or content) archive type.addFile($file, $inArchiveName = null) / addDirectory($directory, $inArchivePath = null) to add one file or one directory, archiveFile($file, $archiveName) / archiveDirectory($directory, $archiveName) to archive one file or directory.Miscellaneous:
phar distribution.Renamed methods extractNode() → extractFiles(), archiveNodes() → archiveFiles(). Original method are still available with @deprecated status.
API changes:
extractNode() → extractFiles(), archiveNodes() → archiveFiles(). Original method are still available with @deprecated status.getFileData() now returns ArchiveEntry instance instead of stdClass. Original object fields are still available with @deprecated status.addFiles() and deleteFiles() now return false when archive is not editable.Improvements:
Exception will be throwed if archive file is not readable.archiveNodes() about handling directory names.addFiles() and deleteFiles().Miscellaneous:
examples/).Nothing published for this version
Added ext-phar adapter for tar archives (if pear/archive_tar is not installed).
ext-phar adapter for tar archives (if pear/archive_tar is not installed).Remove docopt from requirements. Now it's a suggestion.
docopt from requirements. Now it's a suggestion.Added cam (Console Archive Manager) script.
cam (Console Archive Manager) script.Added initial support for CAB archives without extracting.
CAB archives without extracting.die() in source code.Fixed usage of ereg function for PHP >7.
ereg function for PHP >7.Added functionality for adding files in archive.
7z archive number of files and creating new archive.Added support for 7z (by 7zip-cli) archives.
7z (by 7zip-cli) archives.Added support for single-file bz2 (bzip2) and xz (lzma2) archives.
bz2 (bzip2) and xz (lzma2) archives.Removed archive_tar from required packages.
archive_tar from required packages.* Released under the MIT license
First version.
First version.
Your coding agent can read these notes before it upgrades. Set up the MCP server →