我正在尝试使用以下代码从目录创建zip文件,并通过http下载将其提供给用户:
// write the file
file_put_contents($path . "/index.html", $output);
// zip up the contents
chdir($path);
exec("zip -r {$course->name} ./");
$filename = "{$course->name}.zip";
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' .urlencode($filename));
header('Content-Transfer-Encoding: binary');
readfile($filename);
我可以创建zip文件,但是通过http下载它无效。如果我下载使用ftp客户端创建的zip文件,那么Mac的Stuffit Expander就可以解压缩文件了,但是如果我通过http下载它,那么mac unzipper会创建一个无限循环。我的意思是说我下载的文件名为course.zip,然后解压缩文件给出course.zip.cpgz并解压缩该文件再次给出course.zip ..然后再打开。
有人有什么想法吗?
谢谢!
答案 0 :(得分:8)
我遇到了这个问题,结果发现下载的zip文件最初插入了一个新行。
使用ob_clean和flush函数解决
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=".basename($archive_file_name));
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($archive_file_name));
ob_clean();
flush();
echo readfile("$archive_file_name");
答案 1 :(得分:1)
根据karim79的建议,我会将我的评论作为答案:如果您将MIME类型从application / octet-stream更改为application / zip会发生什么?
另外,我看到你正在使用命令行zip程序,但是你没有检查zip的成功,也没有在尝试将它发送给最终用户浏览器之前检查文件是否存在。尝试对文件名进行硬编码,手动使用zip来保证正确形成的zip文件,然后查看您的代码是否会正确地将其吐入浏览器。
答案 2 :(得分:1)
每次请求时重新压缩它都不是一个好主意。只有当ZIP文件不存在时才尝试这样做。
如果是易变文件或只想传输压缩文件的单个小文件,请尝试使用ob_start('ob_gzhandler')
,更简单,更小,更清洁。该文件已传输压缩,但由客户端以原始格式保存。
需要指定Content-Length标头,以允许下载程序知道文件的结尾,允许进度控制,检测文件损坏并避免挂起HTTP会话(如果Connection在Keep中) - 活动模式),也许缺少这个标题是问题的根源。
答案 3 :(得分:0)
您所看到的是存档实用程序未将zip文件识别为zip文件,并尝试压缩zip存档本身。第二个操作只是解压缩创建的第一个文件,因此根本不会实际打开文件。这是由于zip被破坏了。
浏览器可能会在下载过程中以某种方式损坏zip文件(新行转换任何人?)。如上所述,检查mime类型并使用php header()设置正确的MIME类型(application / zip)。