打开PHP Zip文件时下载错误

rxztt3cl  于 2023-05-27  发布在  PHP
关注(0)|答案(5)|浏览(197)

我需要从一个网站下载一个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);
ctzwtxfj

ctzwtxfj1#

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

omhiaaxx2#

在我的情况下,这起了作用
把这个放在php文件的开头

ob_start();

然后,在头文件之后,紧接在readfile之前,将此

while (ob_get_level()) {
    ob_end_clean();
}

收尾

ob_start();//this is new
//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));
while (ob_get_level()) {//this is new
  ob_end_clean();//this is new
}//this is new
readfile($zipname);
w8ntj3qf

w8ntj3qf3#

尝试使用文本编辑器打开zip文件。这样你就可以检查were是否是你代码中的一个php错误(在压缩步骤中)。

kgsdhlau

kgsdhlau4#

检查Web服务器用户是否对要在其中创建ZIP文件的文件夹具有写入权限。尽管有文档说明,ZipArchive::open()仍会静默失败并返回true(即成功),如果它无法创建ZIP文件。此外,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");
}
qlfbtfca

qlfbtfca5#

我有这个问题,但这个解决方案为我解决了它

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

我使用的是旧版本的Silverstripe和我的zip文件不断被损坏,即使数据是明显的在那里。
上面这个晦涩的注解的解决方法是使用ob_clean();很有帮助,我想把这个拿出来作为这个问题的答案。
PHP docs:
ob_clean();丢弃输出缓冲区的内容。
ob_clean();不会像ob_end_clean()那样破坏输出缓冲区。

相关问题