• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • ZipArchive::addEmptyDir()

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

    Add a new directory

    说明

    ZipArchive::addEmptyDir(string $dirname): bool

    Adds an empty directory in the archive.

    参数

    $dirname

    The directory to add.

    返回值

    成功时返回TRUE,或者在失败时返回FALSE

    范例

    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 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!'; 
    } 
    ?>
    
    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
    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();
    ?>
    
    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
    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
    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
    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