php Symfony2 创建和下载 zip 文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20268025/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Symfony2 create and download zip file
提问by BrunoRamalho
I have one application that upload some files and then I can compress as zip file and download.
我有一个应用程序可以上传一些文件,然后我可以将其压缩为 zip 文件并下载。
The export action:
导出操作:
public function exportAction() {
$files = array();
$em = $this->getDoctrine()->getManager();
$doc = $em->getRepository('AdminDocumentBundle:Document')->findAll();
foreach ($_POST as $p) {
foreach ($doc as $d) {
if ($d->getId() == $p) {
array_push($files, "../web/".$d->getWebPath());
}
}
}
$zip = new \ZipArchive();
$zipName = 'Documents-'.time().".zip";
$zip->open($zipName, \ZipArchive::CREATE);
foreach ($files as $f) {
$zip->addFromString(basename($f), file_get_contents($f));
}
$response = new Response();
$response->setContent(readfile("../web/".$zipName));
$response->headers->set('Content-Type', 'application/zip');
$response->header('Content-disposition: attachment; filename=../web/"'.$zipName.'"');
$response->header('Content-Length: ' . filesize("../web/" . $zipName));
$response->readfile("../web/" . $zipName);
return $response;
}
everything is ok until the line header. and everytime I'm going here I got the error: "Warning: readfile(../web/Documents-1385648213.zip): failed to open stream: No such file or directory"
一切正常,直到行标题。每次我去这里时都会收到错误消息:“警告:readfile(../web/Documents-1385648213.zip):无法打开流:没有这样的文件或目录”
What is wrong?
怎么了?
and why when I upload the files, this files have root permissions, and the same happens for the zip file that I create.
以及为什么当我上传文件时,这些文件具有 root 权限,而我创建的 zip 文件也会发生同样的情况。
采纳答案by BrunoRamalho
solved:
解决了:
$zip->close();
header('Content-Type', 'application/zip');
header('Content-disposition: attachment; filename="' . $zipName . '"');
header('Content-Length: ' . filesize($zipName));
readfile($zipName);
apparently closing the file is important ;)
显然关闭文件很重要;)
回答by Vincent Moulene
SYMFONY 3 - 4 example :
SYMFONY 3 - 4 示例:
use Symfony\Component\HttpFoundation\Response;
/**
* Create and download some zip documents.
*
* @param array $documents
* @return Symfony\Component\HttpFoundation\Response
*/
public function zipDownloadDocumentsAction(array $documents)
{
$files = [];
$em = $this->getDoctrine()->getManager();
foreach ($documents as $document) {
array_push($files, '../web/' . $document->getWebPath());
}
// Create new Zip Archive.
$zip = new \ZipArchive();
// The name of the Zip documents.
$zipName = 'Documents.zip';
$zip->open($zipName, \ZipArchive::CREATE);
foreach ($files as $file) {
$zip->addFromString(basename($file), file_get_contents($file));
}
$zip->close();
$response = new Response(file_get_contents($zipName));
$response->headers->set('Content-Type', 'application/zip');
$response->headers->set('Content-Disposition', 'attachment;filename="' . $zipName . '"');
$response->headers->set('Content-length', filesize($zipName));
@unlink($zipName);
return $response;
}
回答by Tomá? Votruba
Since Symfony 3.2+can use file helperto let file download in browser:
由于Symfony 3.2+可以使用文件助手让文件在浏览器中下载:
public function someAction()
{
// create zip file
$zip = ...;
$this->file($zip);
}
回答by seltzlab
It's late but maybe it will be useful to someone else
晚了,但也许对其他人有用
http://symfony.com/doc/2.3/components/http_foundation/introduction.html#serving-files
http://symfony.com/doc/2.3/components/http_foundation/introduction.html#serving-files
回答by Юра Панчук
Work for me. Where $archive_file_name = 'your_path_to_file_from_root/filename.zip'.
为我工作。其中 $archive_file_name = 'your_path_to_file_from_root/filename.zip'。
$zip = new \ZipArchive();
if ($zip->open($archive_file_name, \ZIPARCHIVE::CREATE | \ZIPARCHIVE::OVERWRITE) === TRUE) {
foreach ($files_data as $file_data) {
$fileUri = \Drupal::service('file_system')->realpath($file_data['file_url']);
$filename = $file_data['folder'] . $file_data['filename'];
$zip->addFile($fileUri, $filename);
}
$zip->close();
}
$response = new Response();
$response->headers->set('Cache-Control', 'private');
$response->headers->set('Content-type', 'application/zip');
$response->headers->set('Content-Disposition', 'attachment; filename="' . basename($archive_file_name) . '"');
$response->headers->set('Content-length', filesize($archive_file_name));
// Send headers before outputting anything.
$response->sendHeaders();
$response->setContent(readfile($archive_file_name));
return $response;
回答by Amine
I think its better that you use
我认为你使用它更好
$zipFilesIds = $request->request->get('zipFiles')
foreach($zipFilesIds as $zipFilesId){
//your vérification here
}
with the post variable of your id of zip = 'zipFiles'. Its better of fetching all $_POST variables.
使用 zip = 'zipFiles' id 的 post 变量。最好获取所有 $_POST 变量。
回答by Alessandro Giuliani
To complete vincent response, just add this right before returning response :
要完成文森特响应,只需在返回响应之前添加以下内容:
...
$response->headers->set('Content-length', filesize($zipName));
unlink($zipName);
return $response;

