从服务器上的文件夹压缩,说2个文件,并强行下载最简单的方法是什么?不将“zip”保存到服务器。
$zip = new ZipArchive();
//the string "file1" is the name we're assigning the file in the archive
$zip->addFile(file_get_contents($filepath1), 'file1'); //file 1 that you want compressed
$zip->addFile(file_get_contents($filepath2), 'file2'); //file 2 that you want compressed
$zip->addFile(file_get_contents($filepath3), 'file3'); //file 3 that you want compressed
echo $zip->file(); //this sends the compressed archive to the output buffer instead of writing it to a file.
有人可以验证: 我有一个包含test1.doc,test2.doc和test3.doc
的文件夹使用上面的示例 - file1(file2和file3)可能只是test1.doc等。
我必须对“$ filepath1”做任何事吗?这是包含3个文档的文件夹目录吗?
对不起我的基本问题..
答案 0 :(得分:68)
不幸的是,在CentOS 5.x上使用PHP 5.3.4-dev和Zend Engine v2.3.0我无法使上面的代码工作。我无法获得“无效或单一化的Zip对象”错误消息。因此,为了使其工作,我不得不使用以下代码片段(摘自Jonathan Baltazar在PHP.net手册上的示例,在ZipArchive ::打开页面):
// Prepare File
$file = tempnam("tmp", "zip");
$zip = new ZipArchive();
$zip->open($file, ZipArchive::OVERWRITE);
// Stuff with content
$zip->addFromString('file_name_within_archive.ext', $your_string_data);
$zip->addFile('file_on_server.ext', 'second_file_name_within_archive.ext');
// Close and send to users
$zip->close();
header('Content-Type: application/zip');
header('Content-Length: ' . filesize($file));
header('Content-Disposition: attachment; filename="file.zip"');
readfile($file);
unlink($file);
我知道这与仅使用内存工作不同 - 除非你在ram中有你的tmp区域;-) - 但也许这可以帮助那些正在努力解决上述解决方案的人,就像我一样;并且性能损失不是问题。
答案 1 :(得分:9)
您的代码非常接近。您需要使用文件名而不是文件内容。
$zip->addFile(file_get_contents($filepath1), 'file1');
应该是
$zip->addFile($filepath1, 'file1');
http://us3.php.net/manual/en/function.ziparchive-addfile.php
如果您需要从变量而不是文件添加文件,可以使用addFromString函数。
$zip->addFromString( 'file1', $data );
答案 2 :(得分:5)
如果您有权访问zip命令行实用程序,可以尝试
<?php
$zipped_data = `zip -q - files`;
header('Content-type: application/zip');
header('Content-Disposition: attachment; filename="download.zip"');
echo $zipped_data;
?>
其中files是要压缩的内容,并将位置压缩到zip可执行文件。
当然,这假设是Linux或类似的。在Windows中,我猜你可能会使用其他压缩工具。
还有一个zip extension,用法显示here。
答案 3 :(得分:4)
maraspin的回答是我试过的。奇怪的是,我通过删除引用文件大小的标题行来实现它:
header('Content-Length: ' . filesize($file));
通过上述更改,代码就像轻而易举! 如果没有此更改,我以前会收到以下错误消息:
找不到中心目录签名。此文件不是zip文件,或者它构成多部分存档的一个磁盘。在后一种情况下,中心目录和zipfile注释将在此存档的最后一个磁盘上找到。
测试环境:
操作系统:Ubuntu 10.10 浏览器:Firefox 和默认的LAMP堆栈。答案 4 :(得分:1)
itsols 如果要插入'Content-Length',请执行以下操作:
$length = filesize($file);
header('Content-Length: ' . $length);
我不知道为什么,但如果你把它放在同一行,它会崩溃。
答案 5 :(得分:1)
要动态创建ZIP文件(在内存中),您可以使用phpMyAdmin中的ZipFile
课程:
如何在您自己的应用程序中使用它的示例:
注意:您的ZIP文件将受到PHP内存限制的限制,如果超出限制,会导致存档损坏。
答案 6 :(得分:0)
这对我有用(什么都没有写到磁盘上)
$tmp_file = tmpfile(); //temp file in memory
$tmp_location = stream_get_meta_data($tmp_file)['uri']; //"location" of temp file
$zip = new ZipArchive;
$res = $zip->open($tmp_location, ZipArchive::CREATE);
$zip->addFile($filepath1, 'file1');
$zip->close();
header('Content-type: application/zip');
header('Content-Disposition: attachment; filename="download.zip"');
echo(file_get_contents($tmp_location));