【问题标题】:PHP Zip file download error when opening打开时PHP Zip文件下载错误
【发布时间】:2013-11-13 20:11:58
【问题描述】:

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

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

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

我已尝试使用Download multiple files as a zip-file using php 作为参考。

//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);

【问题讨论】:

  • 您是否查看过使用 HEX 编辑器获得的 ZIP 文件?如果不是,请告诉我们前四个字节是什么。
  • 请同时显示示例内容的添加。到目前为止,您的代码看起来还不错
  • 我怀疑以下两个原因之一。 a) 发生一些 PHP 错误并打印到标准输出,因此它包含在 ZIP 文件中(当然,它已损坏,因为其中不应该有来自 PHP 错误的随机字符:D)。 b) 由于 mod_deflate 或类似的原因,PHP 或网络服务器在其上添加了另一层 GZIP。但是,标头不尊重这一点,因此 ZIP 文件不会被浏览器“解压缩”,因此已损坏。
  • 我花了很长时间寻找与图像文件类似的问题。我的解决方案是在开始输出新标头之前立即添加ob_clean();
  • @Mike W:你是个特别棒的人。我希望我早点知道这一点。有一次,在将服务器升级到 Ubuntu 13.10 后,这对我来说成了一个问题。使用ob_clean(),最终的 zip 文件会变大大约 10kb,并且可以正常工作。我不知道为什么。但我现在可以忘记它了。

标签: php file download zip


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    检查 Web 服务器用户是否对您正在创建 ZIP 文件的文件夹具有写入权限。尽管有文档,ZipArchive::open() 将在无法创建 ZIP 文件时静默失败并返回 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");
    }
    

    【讨论】:

    • 由于某种原因,未包含 zip 文件中的所有内容。因此,按照您的建议,正在下载一个 0 字节大小的 zip 文件。添加您建议的错误检查清楚地表明,在下载之前,该 zip 文件实际上并不存在于服务器上!非常感谢您的修复!我知道这将是我所做的愚蠢的事情! :')
    【解决方案3】:

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

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

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

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

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

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

    【讨论】:

      【解决方案4】:

      尝试添加 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);
        ?>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多