Oihana PHP

untar.php

Table of Contents

Functions

untar()  : true|array<string|int, string>
Extracts a tar archive file into a specified output directory.

Functions

untar()

Extracts a tar archive file into a specified output directory.

untar(string $tarFile, string $outputPath[, array{dryRun?: bool, keepPermissions?: bool, overwrite?: bool, maxExtractedSize?: int|null} $options = [] ]) : true|array<string|int, string>

This function supports regular and compressed tar files (.tar, .tar.gz, .tar.bz2). It can perform a dry run to preview extracted files, optionally preserve file permissions, and control overwriting of existing files.

Which engine extracts

The system tar when there is a GNU one and the decompressor it needs (untarBinaryHandles()), PharData otherwise. The choice is made before anything is written and is not revisited, as it is for writing in tar().

It is not a question of speed: PharData extracts a plain archive at a comparable pace. It is that decompressing with PharData means having PharData write a new .tar first, and its writer refuses any path component over 100 bytes — the ustar limit. Since 1.3.0 tar() delegates to GNU tar, which stores such names without difficulty, so a .tar.gz this library wrote could fail to extract through this one. A stock WordPress carries such a path. The rebuild also costs about twice the archive in memory, and an uncompressed copy on disk beside it.

Both engines honour the four options below and produce the same tree, which is why the guards live in one place, untarAssertExtractable().

Extracting the same archive twice, on the PharData path

It used to fail, with "a phar with that name already exists": PharData::decompress() writes a .tar named after the archive and registers it in an internal list that removing the file does not clear. Phar::unlinkArchive() clears both and corrupted the Zend heap when called from here, so the collision is avoided instead: untarUniqueAlias() gives the archive a uniquely named hard link — no bytes copied — and the .tar inherits that name. Both go at the end.

Parameters
$tarFile : string

Path to the tar archive file to extract.

$outputPath : string

Path to the directory where files will be extracted. The directory will be created if it does not exist.

$options : array{dryRun?: bool, keepPermissions?: bool, overwrite?: bool, maxExtractedSize?: int|null} = []

Optional flags:

  • dryRun: If true, the function does not extract files but returns the list of files that would be extracted. Default: false.
  • keepPermissions: If true, preserves the original file permissions from the archive. Default: false.
  • overwrite: If false, prevents overwriting existing files during extraction. Extraction will fail if a file already exists. Default: true.
  • maxExtractedSize: If set to a positive integer, defines the maximum total uncompressed size (in bytes) accepted during extraction. The archive is pre-scanned and a RuntimeException is thrown before any file is written if the sum of the entries' uncompressed sizes exceeds this limit. Guards against decompression-bomb attacks. Default: null (no limit).
Tags
throws
FileException

If the provided tar file is invalid or inaccessible.

DirectoryException

If the output directory cannot be created or is not writable.

RuntimeException

For extraction errors such as:

  • Path traversal attempts detected inside archive entries.
  • Attempt to overwrite existing files when overwrite is disabled.
  • Total uncompressed size exceeds maxExtractedSize (decompression-bomb protection).
  • Other errors during decompression or extraction.
Exception

Propagates unexpected exceptions during extraction wrapped as RuntimeException.

example
// Basic extraction
untar( '/path/to/archive.tar' , '/output/dir' );

// Extraction with options
untar( '/path/to/archive.tar.gz' , '/output/dir' , [
'overwrite'        => false,
'keepPermissions'  => true
]);

// Dry-run: preview contents without extracting
$files = untar( '/path/to/archive.tar' , '/output/dir' , [ 'dryRun' => true ] );
print_r( $files );

// Prevent overwriting, will throw RuntimeException if file exists
untar( '/path/to/archive.tar' , '/output/dir' , [ 'overwrite' => false ] );
author

Marc Alcaraz (ekameleon)

since
1.0.0
Return values
true|array<string|int, string> —

Returns true on successful extraction, or an array of file paths (relative to archive root) if dryRun is enabled.

On this page

Search results