PHP Conference Japan 2024

ZipArchive::addEmptyDir

(PHP 5 >= 5.2.0, PHP 7, PHP 8, PECL zip >= 1.8.0)

ZipArchive::addEmptyDirAdd a new directory

Descrizione

public ZipArchive::addEmptyDir(string $dirname, int $flags = 0): bool

Adds an empty directory in the archive.

Elenco dei parametri

dirname

The directory to add.

flags

Bitmask consisting of ZipArchive::FL_ENC_GUESS, ZipArchive::FL_ENC_UTF_8, ZipArchive::FL_ENC_CP437. The behaviour of these constants is described on the ZIP constants page.

Valori restituiti

Restituisce true in caso di successo, false in caso di fallimento.

Log delle modifiche

Versione Descrizione
8.0.0, PECL zip 1.18.0 flags was added.

Esempi

Example #1 Create a new directory in an archive

<?php
$zip
= new ZipArchive;
if (
$zip->open('test.zip') === TRUE) {
if(
$zip->addEmptyDir('newDirectory')) {
echo
'Created a new root directory';
} else {
echo
'Could not create the directory';
}
$zip->close();
} else {
echo
'failed';
}
?>
add a note

User Contributed Notes 9 notes

up
4
hunter666 at abv dot bg
14 years ago
Add folder and sub-directories to zip archive.

<?php
$archive_name
= "archive.zip"; // name of zip file
$archive_folder = "folder"; // the folder which you archivate

$zip = new ZipArchive;
if (
$zip -> open($archive_name, ZipArchive::CREATE) === TRUE)
{
$dir = preg_replace('/[\/]{2,}/', '/', $archive_folder."/");

$dirs = array($dir);
while (
count($dirs))
{
$dir = current($dirs);
$zip -> addEmptyDir($dir);

$dh = opendir($dir);
while(
$file = readdir($dh))
{
if (
$file != '.' && $file != '..')
{
if (
is_file($file))
$zip -> addFile($dir.$file, $dir.$file);
elseif (
is_dir($file))
$dirs[] = $dir.$file."/";
}
}
closedir($dh);
array_shift($dirs);
}

$zip -> close();
echo
'Archiving is sucessful!';
}
else
{
echo
'Error, can\'t create a zip file!';
}
?>
up
1
thomas dot rubbert at yahoo dot de
15 years ago
Here's a stack-based way to zip a directory. No recursion, no function, no class:

<?php
$zip
= new ZipArchive();
$zip->open('test.zip', ZipArchive::CREATE);

$dirName = 'test';

if (!
is_dir($dirName)) {
throw new
Exception('Directory ' . $dirName . ' does not exist');
}

$dirName = realpath($dirName);
if (
substr($dirName, -1) != '/') {
$dirName.= '/';
}

/*
* NOTE BY danbrown AT php DOT net: A good method of making
* portable code in this case would be usage of the PHP constant
* DIRECTORY_SEPARATOR in place of the '/' (forward slash) above.
*/

$dirStack = array($dirName);
//Find the index where the last dir starts
$cutFrom = strrpos(substr($dirName, 0, -1), '/')+1;

while (!empty(
$dirStack)) {
$currentDir = array_pop($dirStack);
$filesToAdd = array();

$dir = dir($currentDir);
while (
false !== ($node = $dir->read())) {
if ((
$node == '..') || ($node == '.')) {
continue;
}
if (
is_dir($currentDir . $node)) {
array_push($dirStack, $currentDir . $node . '/');
}
if (
is_file($currentDir . $node)) {
$filesToAdd[] = $node;
}
}

$localDir = substr($currentDir, $cutFrom);
$zip->addEmptyDir($localDir);

foreach (
$filesToAdd as $file) {
$zip->addFile($currentDir . $file, $localDir . $file);
}
}

$zip->close();
?>
up
1
lea dot gris at noiraude dot net
7 months ago
The <code>addEmptyDir</code> method does not handle permissions bits and directory <code>mtime</code>. These need to be set separately after the directory has been created in the Zip Archive.

Note that setting the <code>mtime</code> is only available since PHP >= 8.0, so it will stay the current timestamp of the <code>addEmptyDir</code> call with PHP 7.4 and below.

Here is a function to fix both permissions and <code>mtime</code> of a directory in a Zip Archive.

<pre><code lang="php">
function fixDirAttributes(ZipArchive $zip, string $path, string $name)
{
// Gets the index of the directory in the Zip archive
$indexInZip = $zip->locateName('/' === mb_substr($name, -1) ? $name : $name . '/');
if (false !== $indexInZip) { // Name found
if (method_exists($zip, 'setMtimeIndex')) { // PHP >= 8.0.0, PECL zip >= 1.16.0
$zip->setMtimeIndex($indexInZip, filemtime($path)); // Fixes the mtime of the directory
}
$filePerms = fileperms($path); // Gets permissions on the directory
if (false !== $filePerms) { // filePerms supported
$attr = $filePerms << 16; // Left-shift permission to git the external attributes value
$zip->setExternalAttributesIndex($indexInZip, \ZipArchive::OPSYS_UNIX, $attr);
}
}
}
</pre></code>
up
0
iunknownvb at gmail dot com
1 year ago
I have modified thomas dot rubbert at yahoo dot de a little bit

$uploads_dir =storage_path().'/app/public/files/' ;
if(!file_exists($uploads_dir)){
mkdir($uploads_dir,0777,true);
}
$zip_file=$uploads_dir.'download.zip';
if(file_exists($zip_file)){
unlink($zip_file);
}
$zip = new \ZipArchive();
if (!$zip->open($zip_file, \ZIPARCHIVE::CREATE)) {
http_response_code(501);
echo 'Zip creation failed';
die();
}
$img=$uploads_dir.'img';

$dirName = realpath($img);
if (substr($dirName, -1) != DIRECTORY_SEPARATOR) {
$dirName.= DIRECTORY_SEPARATOR;
}
$dirStack = array($dirName);
//Find the index where the last dir starts
$cutFrom = strrpos(substr($dirName, 0, -1), DIRECTORY_SEPARATOR)+1;
while (!empty($dirStack)) {
$currentDir = array_pop($dirStack);
$filesToAdd = array();
$dir = dir($currentDir);
while (false !== ($node = $dir->read())) {
if (($node == '..') || ($node == '.')) {
continue;
}
if (is_dir($currentDir . $node)) {
array_push($dirStack, $currentDir . $node . DIRECTORY_SEPARATOR);
}
if (is_file($currentDir . $node)) {
$filesToAdd[] = $node;
}
}
$localDir =str_replace(DIRECTORY_SEPARATOR,'/',substr($currentDir, $cutFrom));
$zip->addEmptyDir($localDir);
foreach ($filesToAdd as $file) {
$zip->addFile($currentDir . $file, $localDir . $file);
}
}
// any additional files
$db=$uploads_dir.'databse.db';
//$zip->addFromString(basename($db), file_get_contents($db));
$zip->addFile($db, basename($db));
$zip->close();
up
0
pagetronic
16 years ago
addEmptyDir doesn't exist now,
use $zip->addFile($file, $dir.$fichier);

nothing on the net about this,

addEmptyDir work on Ubuntu but not on Debian Etch
up
0
benjamin dot seiller at antwerpes dot de
16 years ago
There is kind of a bug in the method
ZipArchive::addFile
which affects the class ZipFolder below.
It is related to the numer of max filehandles of the OS.

As workaround add a file-counter to the class and close + reopen the archive if a certain number of files (directories count as files!) is reached.

For more details see here:
http://de.php.net/manual/en/function.ziparchive-addfile.php
or go directly here
http://bugs.php.net/bug.php?id=40494
or here
http://pecl.php.net/bugs/bug.php?id=9443
up
-1
tahazit dot co dot il at gmail dot com
10 years ago
On PHP >5.4, This function will create a file, not a directory.

For instance:

$zip->addEmptyDir ( 'path/to/dir/' );

will create the folders "path/", and "path/to/", and a dummy 0-byte file named "dir" in the latter.
If then we add a file to that dir, say like this:

$zip->addFromString ( 'path/to/dir/file.txt', $data );

the result will be a SEPARATE folder named "dir" next to the dummy "dir" file. The "dir" folder will contain the file "file.txt".

This was tested on an APACHE server running PHP 5.4
up
-2
D.Jann
16 years ago
I've brought a little modification to dayjo's code, so it wouldn't re-create the whole structure of your working drive in the zip file:

<?php
// Function to recursively add a directory,
// sub-directories and files to a zip archive
function addFolderToZip($dir, $zipArchive, $zipdir = ''){
if (
is_dir($dir)) {
if (
$dh = opendir($dir)) {

//Add the directory
if(!empty($zipdir)) $zipArchive->addEmptyDir($zipdir);

// Loop through all the files
while (($file = readdir($dh)) !== false) {

//If it's a folder, run the function again!
if(!is_file($dir . $file)){
// Skip parent and root directories
if( ($file !== ".") && ($file !== "..")){
addFolderToZip($dir . $file . "/", $zipArchive, $zipdir . $file . "/");
}

}else{
// Add the files
$zipArchive->addFile($dir . $file, $zipdir . $file);

}
}
}
}
}
?>

If you don't specify the third parameter (zipdir), the directory you're adding will be added at the root of the zip file.

D.Jann
up
-3
Anonymous
16 years ago
Here's a simple recurring function to add a directory, all sub-directories and all files to an already created zip file;

<?php
// Function to recursively add a directory,
// sub-directories and files to a zip archive
function addFolderToZip($dir, $zipArchive){
if (
is_dir($dir)) {
if (
$dh = opendir($dir)) {

//Add the directory
$zipArchive->addEmptyDir($dir);

// Loop through all the files
while (($file = readdir($dh)) !== false) {

//If it's a folder, run the function again!
if(!is_file($dir . $file)){
// Skip parent and root directories
if( ($file !== ".") && ($file !== "..")){
addFolderToZip($dir . $file . "/", $zipArchive);
}

}else{
// Add the files
$zipArchive->addFile($dir . $file);

}
}
}
}
}
?>

Would be nice to see more input on these functions :)

Dayjo
To Top