我正在构建一个接口,它允许从服务器路径收集PDF文件,并立即下载压缩文件,这在大多数情况下都可以正常工作。现在,一些PDF文件不工作,意味着如果zip包含一个不工作的文件,整个下载将不会执行。
现在我尝试了许多不同大小的文件。我可以看出,大多数大于10MB的文件都不工作,但一个文件(15MB)正在工作,所以它不能是导致此错误的文件大小-对吗?
发生的是根本没有下载。此外,还尝试读取"$zip->addfile"和"$zip->close"的结果,但这都是正确的,即使不会执行下载。任何可能导致这个错误的想法,或者至少一些关于如何发现这个问题的提示?
过程中变量的(x)调试检查在工作时间和不工作时间之间没有区别。唯一的区别是文件大小和路径。
下面是我用来构建zip的代码:
public function downloadFiles() {
$myFiles = $this->Session->read('Files.MyFiles');
if(count($myFiles)) {
// build zip
$zipname = 'amaz_photos_' . time() . '.zip';
$zip = new ZipArchive();
$zip->open($zipname, ZipArchive::CREATE);
foreach($myFiles as $file) {
if($file['type'] == 'directory') {
$dirName = str_replace('/', '', substr($file['path'], strrpos($file['path'], '/'), (strlen($file['path']) - strrpos($file['path'], '/'))));
$zip->addEmptyDir($dirName);
$this->addFolderToZip($file['path'] . '/', $zip, $dirName . '/');
} else {
$zip->addFile($file['path'], str_replace('/', '', substr($file['path'], strrpos($file['path'], '/'), (strlen($file['path']) - strrpos($file['path'], '/')))));
}
}
$zip->close();
// get(send) zip
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename=' . $zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
ignore_user_abort(true);
unlink($zipname);
}
// clear"myFiles"
//$this->Session->write('Files.MyFiles', array());
$this->redirect(array(
'controller' => 'pages',
'action' => 'display'
));
}
毕竟,我尝试用包括Adobe原版在内的几个PDF阅读器打开受影响的文件,以确定它是否已损坏,但是?我?t?S?似乎没有。
这将发生在可打开的zip文件中,但下载不会以任何方式启动。我发现,在没有开始下载的特殊情况下,与工作时间相比,网络框架上没有设置响应头("application/zip")。
我还发现了:假设我有一个文件夹,里面有20个文件,但没有下载。我尝试选择文件1-10:下载,然后我尝试下载文件11-20:下载,然后我尝试下载文件1-20:不下载,然后我尝试了两次混合模式,首先是偶数文件2、4、6、8。(1-20),之后是奇数文件1、3、5、7、。(1-20):每个都没有下载。这说明错误不属于特定文件。
对于如何确定此错误的触发器有什么建议吗?
Update:
I was able to download the generated zip-file doing these steps:
Trigger 'create & download zip-file'
It creates a zip-file but not download it
Type the generated zip-files filename in the code to download it on the next procedure (e. g."$zipname ="generatedOnStep1.zip").
Trigger 'create & download zip-file' again
It does not download the (recently) generated file, but the file i generated in step 1. So it seems that: Generating Zip-Files is working AND downloading that same zip-File is working, but not at once and only in some unknown combinations.
…
Update 2:
Since I was not able to determine the issue nor fix it, I ended up redesigning the whole process, to redirect to the generated zip-file instead of"readfile" it. Some features had to be sourced out but anyways it works this way.
你试过检查压缩文件中PDF文件的大小吗?有尺码吗?与原始文件相比大小是多少?你也没有给我们addfoldertozip的代码。
在这种情况下,由于添加了单个文件,因此不使用addFolderToZip()。你只要记着跳过。不管怎样,你让我想到了下载后不要丢弃文件的想法。可以查看PDF,大小比未压缩的大2 MB。所以看起来一切正常,但下载没有开始。我有大的视频文件可以下载,所以我很确定它不是关于任何内存限制。此外,硬盘空间也相当空(足够)。
只是要清楚:zip是正确生成的,可以被拒绝,并且可以查看pdf。但是下载并不是从特定的PDF开始的。
这种情况发生的频率有多高,您是否尝试不删除生成的zip文件以查看zip文件中的实际内容,或者是否实际创建了这些文件?是否检查了PHP超时(运行时间限制或内存限制?)。如果没有下载,是否会得到一个空白页(可能表示有错误)?如果是这样,请检查php/webserver的错误日志。(btw,time()仅每秒唯一,请注意,如果同时执行两个请求,则可能会导致问题。也许可以试试tempnam)。
是的,我试着保存文件。这将发生在可打开的zip文件中,但下载不会以任何方式启动。我发现,在没有开始下载的特殊情况下,与工作时间相比,网络框架上没有设置响应头("application/zip")。日志是空的。
什么cakephp版本?
我通过重定向到zip文件而不是"readfile"来解决这个问题。这划分了许多逻辑,但按预期工作。
试试这个…取下readfile($zipname);,更换为:
/* make sure no other functions
holding this file */
$filehandle = fopen($zipname,"r");
while (!feof($filehandle)) {
/* lets read the file by pieces and
send it to user's browser */
echo fread($filehandle, 8192);
}
fclose($filehandle);
希望这有帮助。
它会导致同样的行为。如果我手动压缩,它会下载zip,如果我按ziparchive压缩,它会创建zip,但不会下载。这里发生了一些非确定性的奇迹……
即使你的回答没有解决我的问题,它也让我重新设计了流程,在创建zip后重定向到文件。谢谢你的产品。
谢谢。。。如果你解决了你的问题,请告诉我…我看到你的问题被更新了。我会根据你的最新情况进一步调查,并通知你。