压缩文件夹内的所有文件并下载生成的.zip文件。

35

首先,这是我的文件夹结构:

images/

image1.png
image11.png
image111.png
image223.png
generate_zip.php

这是我的 generate_zip.php 文件:

<?php

    $files = array($listfiles);

    $zipname = 'adcs.zip';
    $zip = new ZipArchive;
    $zip->open($zipname, ZipArchive::CREATE);
    foreach ($files as $file) {
      $zip->addFile($file);
    }
    $zip->close();

    header('Content-Type: application/zip');
    header("Content-Disposition: attachment; filename='adcs.zip'");
    header('Content-Length: ' . filesize($zipname));
    header("Location: adcs.zip");

    ?>

如何从 "images/" 文件夹中收集除 "generate_zip.php" 之外的所有文件,并将其制作成可下载的 .zip 文件?在这种情况下,"images/" 文件夹始终具有不同的图像。是否可能?

6个回答

69

=======可行的解决方案!======

包括所有子文件夹:

new GoodZipArchive('path/to/input/folder',    'path/to/output_zip_file.zip') ;

起初,包含这个代码片段


3
如果这是最好的解决方案,我不知道,但我点赞了它,因为这对我也起作用。 - Jakob Sternberg
谢谢!只是好奇,我们如何包含多个文件夹? - NiCk Newman
1
我正在使用Angular的服务调用此文件。该文件未被下载。有什么建议吗? - m1crdy
这个可以运行,但是我该如何让用户通过打开保存对话框窗口将其保存到其他地方,而不是保存在原始文件夹的相同位置。 - user3758078
1
@Ngob 已修复。 - T.Todua
显示剩余3条评论

31
这将确保不会添加扩展名为 .php 的文件:
   foreach ($files as $file) {
        if(!strstr($file,'.php')) $zip->addFile($file);
    }

编辑:这是完整的代码重写:

<?php

    $zipname = 'adcs.zip';
    $zip = new ZipArchive;
    $zip->open($zipname, ZipArchive::CREATE);
    if ($handle = opendir('.')) {
      while (false !== ($entry = readdir($handle))) {
        if ($entry != "." && $entry != ".." && !strstr($entry,'.php')) {
            $zip->addFile($entry);
        }
      }
      closedir($handle);
    }

    $zip->close();

    header('Content-Type: application/zip');
    header("Content-Disposition: attachment; filename='adcs.zip'");
    header('Content-Length: ' . filesize($zipname));
    header("Location: adcs.zip");

    ?>

好的,但如何列出images/目录中的所有文件?放在数组里面吗? - Ygor Montenegro
http://php.net/manual/zh/function.readdir.php 在这方面提供了您所需的内容,示例#2可能是最简单的。您可以将 if ($entry!=“。”&& $entry!=“..”)扩展为 if ($entry!=“。”&& $entry!=“..”&&!strstr($entry,'.php')) 并在该循环中执行 zip 添加,而不是使用我上面的示例。 - skrilled
已经尝试过了,但是如何将整个结果放入array()中呢? - Ygor Montenegro
我已经编辑了我的答案,加入了你的代码,就像我认为你想要的那样 :) - skrilled
1
如果 ($handle = opendir('../adc/')) { while (false !== ($entry = readdir($handle))) { if ($entry != "." && $entry != "..") { array_push($listfiles, "'$entry, "); } } closedir($handle); }$files = array(); 仍未生成... - Ygor Montenegro
显示剩余3条评论

1

如果您只需要从目录中获取特定文件以创建ZipArchive,您可以使用glob()函数来完成。

<?php
    $zip = new ZipArchive;
    $download = 'download.zip';
    $zip->open($download, ZipArchive::CREATE);
    foreach (glob("images/*.png") as $file) { /* Add appropriate path to read content of zip */
        $zip->addFile($file);
    }
    $zip->close();
    header('Content-Type: application/zip');
    header("Content-Disposition: attachment; filename = $download");
    header('Content-Length: ' . filesize($download));
    header("Location: $download");
 ?>

如果您尝试列出存储了非常多文件(超过100,000个)的目录中的文件,请勿使用glob()。您会收到“内存分配大小为XYZ字节已耗尽…”错误。

readdir()是更稳定的方法。


1
我采用了way2vin的解决方案。但是我不得不用以下代码替换: $zip->addFromString(basename($file), file_get_contents($file));
这样就可以了。在创建.zip文件中发现了这个方法。

0
<?php 
ob_start();
$zip = new ZipArchive; 
$zip->open('sample.zip',  ZipArchive::CREATE);
$srcDir = "C:\\xampp\\htdocs\\uploads"; //location of the directory
$files= scandir($srcDir);
print_r($files);  // to check if files are actually coming in the array

unset($files[0],$files[1]);
foreach ($files as $file) {
    $zip->addFile($srcDir.'\\'.$file, $file);
    echo "bhandari";
}
$zip->close();

$file='sample.zip';
if (headers_sent()) {
    echo 'HTTP header already sent';
} else {
    if (!is_file($file)) {
        header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
        echo 'File not found';
    } else if (!is_readable($file)) {
        header($_SERVER['SERVER_PROTOCOL'].' 403 Forbidden');
        echo 'File not readable';
    } else {
        header($_SERVER['SERVER_PROTOCOL'].' 200 OK');
        header("Content-Type: application/zip");
        header("Content-Transfer-Encoding: Binary");
        header("Content-Length: ".filesize($file));
        header("Content-Disposition: attachment; filename=\"".basename($file)."\"");
        while (ob_get_level()) {
            ob_end_clean();
          }
        readfile($file);
        exit;
    }
}



?>`enter code here`

请注意:不要忘记使用ob_start();和end.

0
将您的foreach循环更改为以下内容,以排除generate_zip.php
 foreach ($files as $file) {
     if($file != "generate_zip.php"){
        $zip->addFile($file);
     }
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接