我需要从网站下载 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);
尝试使用文本编辑器打开 zip 文件。 这样您就可以检查代码中是否存在 php 错误(在压缩步骤期间)。
检查 Web 服务器用户是否对您在其中创建 ZIP 文件的文件夹具有写入权限。尽管有文档,如果无法创建 ZIP 文件,
ZipArchive::open()
将默默失败并返回 true
(即成功)。此外,ZipArchive::addFile()
似乎会向这个不存在的存档添加任意数量的文件,也不会报告错误。第一个出现错误的时刻是 ZipArchive::close() 返回“false”时。错误日志中也没有出现任何错误消息。
Readfile()
will 向日志报告错误并失败,因此结果是本地硬盘上的零长度 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");
}
我遇到了这个问题,但这个解决方案为我解决了它
Add ob_clean(); just before your new output headers.
我使用的是旧版本的 Silverstripe,尽管数据明显存在,但我的 zip 文件不断损坏。
上面这个晦涩注释的解决方案是使用 ob_clean();很有帮助,我想把它作为这个问题的答案。
来自 PHP 文档:
ob_clean();
丢弃输出缓冲区的内容。
ob_clean();
不会像 ob_end_clean() 那样破坏输出缓冲区。
尝试添加 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);
?>
就我而言,这有效
将其放在 php 文件的开头
ob_start();
然后,在标题之后和读取文件之前放置此
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);
$zip->close();
ob_clean(); <-- this is the asnwer
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$nombreDir.'.zip');
header('Content-Length: ' . filesize($directorioCreado . '.zip'));
header('cache-control: no-cache, must-revalidate');
header('Expires: 0');
readfile($directorioCreado . '.zip');