ZipArchive::addEmptyDir

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

ZipArchive::addEmptyDir新しいディレクトリを追加する

説明

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

空のディレクトリをアーカイブに追加します。

パラメータ

dirname

追加するディレクトリ。

flags

以下のビットマスクの組み合わせ: ZipArchive::FL_ENC_GUESS, ZipArchive::FL_ENC_UTF_8, ZipArchive::FL_ENC_CP437。 これらの定数の振る舞いは、定義済みの定数 で説明しています。

戻り値

成功した場合に true を、失敗した場合に false を返します。

変更履歴

バージョン 説明
8.0.0, PECL zip 1.18.0 flags が追加されました。

例1 アーカイブ内での新規ディレクトリの作成

<?php
$zip
= new ZipArchive;
if (
$zip->open('test.zip') === TRUE) {
if(
$zip->addEmptyDir('newDirectory')) {
echo
'新しいディレクトリを作成しました';
} else {
echo
'ディレクトリが作成できませんでした';
}
$zip->close();
} else {
echo
'失敗しました';
}
?>
add a note

User Contributed Notes 9 notes

up
4
hunter666 at abv dot bg
15 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
16 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
1 year 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
2 years 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
17 years ago
There is kind of a bug in the methodZipArchive::addFilewhich 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.phpor go directly herehttp://bugs.php.net/bug.php?id=40494or herehttp://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 archivefunction 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