1
//Get the directory to zip
$filename_no_ext=$_GET['directtozip'];
// we deliver a zip file
header("Content-Type: archive/zip");
// filename for the browser to save the zip file
header("Content-Disposition: attachment; filename=$filename_no_ext".".zip");
// get a tmp name for the .zip
$tmp_zip = tempnam ("tmp", "tempname") . ".zip";
//change directory so the zip file doesnt have a tree structure in it.
chdir('uploads/'.$_GET['directtozip']);

// zip the stuff (dir and all in there) into the tmp_zip file
exec('zip '.$tmp_zip.' *');

// calc the length of the zip. it is needed for the progress bar of the browser
header('Content-Length: ' . filesize($file)); 
// deliver the zip file
$fp = fopen("$tmp_zip","r");
echo fpassthru($fp);
// clean up the tmp zip file
unlink($tmp_zip);

以下代码为我创建了空白 zip 文件。

这是我的 ip localhostfilemanager/zip_folder.php?directtozip=Screenshots

目录树

截图
- Image.jpg
上传
^截图
- Image.jpg

而且它基本上没有得到任何这些文件。这是为什么?我最近在 google 中搜索了几乎所有代码,并且有效的代码不是基于标题输出,只是在目录 ./ 中创建 zip。你能给我一个我绝望的工作代码吗:(

4

3 回答 3

2

将所有文件复制到临时位置,然后使用它创建临时文件夹的 zip 文件,然后删除临时文件夹

/** 
* Function will recursively zip up files in a directory and all sub directories / files in the specified source
* @param - $source - directory that you want contents of zipping - note does NOT zip primary directory only files and folders within directory
* @param - $destination - filepath and filename you are storing your created zip files in (could also be used to stream files down using the correct stream headers) eg: "/createdzips/zippy.zip"
* @return nothing - nada - null - zero - zilch - zip :)
*/
function zipcreate($source, $destination) {
    if (!extension_loaded('zip') || !file_exists($source)) {
        return false;
    }
    $zip = new ZipArchive();
    if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
        return false;
    }
    $source = str_replace('\\', '/', realpath($source));
    if (is_dir($source) === true) {
        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
        foreach ($files as $file) {
            $file = str_replace('\\', '/', realpath($file));
            if (is_dir($file) === true) {
                $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
            } else if (is_file($file) === true) {
                $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
            }
        }
    } else if (is_file($source) === true) {
        $zip->addFromString(basename($source), file_get_contents($source));
    }
    return $zip->close();
}

zipcreate("c:/xampp/htdocs/filemanager/Screenshots", "c:/xampp/htdocs/filemanager/uploads/screenshots.zip");


header("Content-Description: File Transfer");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"c:/xampp/htdocs/filemanager/uploads/screenshots.zip\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize("c:/xampp/htdocs/filemanager/uploads/screenshots.zip"));
于 2013-11-01T16:26:36.297 回答
1

为什么不试试ZipArchive

<?php
$zip = new ZipArchive;
$filename = "text.zip";
$filepath = "path/to/zip";
if ($zip->open('test.zip') === TRUE) {
    $zip->addFile('/path/to/index.txt', 'newname.txt');
    $zip->close();
    header("Content-Description: File Transfer");
    header("Content-type: application/octet-stream");
    header("Content-Disposition: attachment; filename=\".$filename."\");
    header("Content-Transfer-Encoding: binary");
    header("Content-Length: ".filesize($filepath.$filename));
} else {
    echo 'failed';
}
?>

它较旧,但是对于您要尝试做的事情,它要干净得多。

压缩一个文件夹(包括它自己)。用法:HZip::zipDir('/path/to/sourceDir', '/path/to/out.zip');

<?php 
class HZip 
{ 
  /** 
   * Add files and sub-directories in a folder to zip file. 
   * @param string $folder 
   * @param ZipArchive $zipFile 
   * @param int $exclusiveLength Number of text to be exclusived from the file path. 
   */ 
  private static function folderToZip($folder, &$zipFile, $exclusiveLength) { 
    $handle = opendir($folder); 
    while (false !== $f = readdir($handle)) { 
      if ($f != '.' && $f != '..') { 
        $filePath = "$folder/$f"; 
        // Remove prefix from file path before add to zip. 
        $localPath = substr($filePath, $exclusiveLength); 
        if (is_file($filePath)) { 
          $zipFile->addFile($filePath, $localPath); 
        } elseif (is_dir($filePath)) { 
          // Add sub-directory. 
          $zipFile->addEmptyDir($localPath); 
          self::folderToZip($filePath, $zipFile, $exclusiveLength); 
        } 
      } 
    } 
    closedir($handle); 
  } 

  /** 
   * Zip a folder (include itself). 
   * Usage: 
   *   HZip::zipDir('/path/to/sourceDir', '/path/to/out.zip'); 
   * 
   * @param string $sourcePath Path of directory to be zip. 
   * @param string $outZipPath Path of output zip file. 
   */ 
  public static function zipDir($sourcePath, $outZipPath) 
  { 
    $pathInfo = pathInfo($sourcePath); 
    $parentPath = $pathInfo['dirname']; 
    $dirName = $pathInfo['basename']; 

    $z = new ZipArchive(); 
    $z->open($outZipPath, ZIPARCHIVE::CREATE); 
    $z->addEmptyDir($dirName); 
    self::folderToZip($sourcePath, $z, strlen("$parentPath/")); 
    $z->close(); 
  } 
} 
?>

根据用法:方法是静态的,因此您不需要像第一个示例中那样实例化选项,只需使用层次运算符直接调用函数

HZip::zipDir('/path/to/sourceDir', '/path/to/out.zip');
于 2013-11-01T16:17:45.080 回答
0

需要注意的两点 1. exec 中的用户 -r ,如果您还想包含子目录。2. 将 * 替换为 . 在你的 exec 命令中,它会压缩。

于 2013-11-01T16:43:36.317 回答