麻烦在PHP中压缩目录

时间:2013-11-01 16:16:02

标签: php zip

//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 =截图

目录树

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

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

3 个答案:

答案 0 :(得分: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"));

答案 1 :(得分: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');

答案 2 :(得分:0)

要注意两点 1.如果要包含子目录,请在exec中使用-r。 2.替换*。在你的exec命令中,它将压缩。