2

我需要从网站下载一个 zip 文件,因为我需要在一次下载中合并多个文件(最多 100 个单独的文件)

尝试创建 zip 文件时,它会按预期下载,文件名也按预期以“YYYY.MM.DD - HH.MM.SS”格式显示。尝试在 Windows 7 (或 winzip)中打开 zip 文件时出现我的问题- 我收到以下错误消息。这种情况在多次尝试中反复发生。

我假设我在对 zip 文件的创建或下载进行编码时出错,而不是 zip 文件格式本身是一个问题,因为我可以打开不同的 zip 文件 - 谁能看到我可能犯的错误?(错误图像下方包含的代码)

我曾尝试使用 php作为参考,将下载多个文件作为 zip 文件。

//backup file name based on current date and time
$filename = date("Y.m.j - H.i.s");
//name of zip file used when downloading
$zipname = 'temp.zip';
//create new zip file
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
//yes, I know the zip file is empty currently - I've cut the code from here for
//now as the zip file doesn't function with / without it currently
$zip->close();

//download file from temporary file on server as '$filename.zip'
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$filename.'.zip');
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
4

4 回答 4

4

尝试使用文本编辑器打开 zip 文件。通过这种方式,您可以检查代码中是否存在 php 错误(在压缩步骤期间)。

于 2015-02-17T14:58:48.730 回答
3

检查 Web 服务器用户是否对您正在创建 ZIP 文件的文件夹具有写入权限。尽管有文档,但如果无法创建 ZIP 文件,ZipArchive::open()它将静默失败并返回(即成功)。true此外,ZipArchive::addFile()似乎会向这个不存在的存档添加任意数量的文件,也不会报告错误。出现错误的第一个点是 ZipArchive::close() 返回“false”时。错误日志中也不会出现错误消息。

Readfile() 将向日志报告错误并失败,因此结果是本地硬盘上的零长度 ZIP 文件。

原因似乎是 ZipArchive 类只是在内存中组装一个文件列表,直到它关闭,此时它将所有文件组装到 Zip 文件中。如果这不能完成,则ZipArchive::close()返回false

注意:如果 zip 文件为空,则可能根本不会创建!您的下载将继续,但readfile()会失败,您将下载一个长度为零的 ZIP 文件。

该怎么办?

在您的代码中添加一些错误检查以报告其中的一些:

$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);

// Add your files here

if ($zip->close() === false) {
   exit("Error creating ZIP file");
};


//download file from temporary file on server as '$filename.zip'
if (file_exists($zipname)) {

    header('Content-Type: application/zip');
    header('Content-disposition: attachment; filename='.$filename.'.zip');
    header('Content-Length: ' . filesize($zipname));
    readfile($zipname);
} else {
    exit("Could not find Zip file to download");
}
于 2013-11-13T21:45:20.437 回答
2

我遇到了这个问题,但是这个解决方案为我解决了这个问题

Add ob_clean(); just before your new output headers.

我使用的是旧版本的 Silverstripe 并且我的 zip 文件经常被损坏,即使数据在那里可见。

上面这个晦涩的注释的解决方案是使用 ob_clean(); 很有帮助,我想把它作为这个问题的答案。

来自 PHP 文档:
ob_clean();丢弃输出缓冲区的内容。

ob_clean();不会像 ob_end_clean() 那样破坏输出缓冲区。

于 2020-12-20T22:07:20.700 回答
0

尝试添加 ob_end_clean(); 在标题之前

    <?php
$zip = new ZipArchive();
$zip_name = $name.".zip"; // Zip name
$tmpFile=APPPATH.'../'.$zip_name;
$zip->open($zip_name,  ZipArchive::CREATE);
foreach ($images as $files) {
  if(!empty($files->cloudinary_img_url)){
  $zip->addFromString(basename($files->car_images),  file_get_contents(getImagesDropbox($files->cloudinary_img_url)));  
 
  }
  else{
   echo"file does not exist";
  }
}  
$zip->close();
 ob_end_clean();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename="'.$zip_name.'"');
header('Content-Length: ' . filesize($tmpFile));
readfile($tmpFile);
unlink($tmpFile);
  ?>
于 2022-01-19T12:24:59.567 回答