Symfony2创建并下载zip文件

时间:2013-11-28 13:56:27

标签: php symfony zip

我有一个应用程序上传了一些文件然后我可以压缩为zip文件并下载。

导出操作:

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;
    }

在行标题之前一切正常。 每次我要去这里我都会收到错误:“警告:readfile(../ web / Documents-1385648213.zip):无法打开流:没有这样的文件或目录”

有什么问题?

以及为什么当我上传文件时,这些文件具有root权限,对于我创建的zip文件也是如此。

8 个答案:

答案 0 :(得分:18)

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;
}

答案 1 :(得分:8)

解决:

$zip->close();
header('Content-Type', 'application/zip');
header('Content-disposition: attachment; filename="' . $zipName . '"');
header('Content-Length: ' . filesize($zipName));
readfile($zipName);

显然关闭文件很重要;)

答案 2 :(得分:2)

答案 3 :(得分:1)

由于 Symfony 3.2 + 可以使用file helper来允许在浏览器中下载文件:

public function someAction()
{
    // create zip file
    $zip = ...;

    $this->file($zip);    
}

答案 4 :(得分:0)

我认为你使用

更好
$zipFilesIds = $request->request->get('zipFiles')
foreach($zipFilesIds as $zipFilesId){
  //your vérification here 
}

使用你的id = zip ='zipFiles'的post变量。它更好地获取所有$ _POST变量。

答案 5 :(得分:0)

要完成文森特的回复,只需在返回回复之前添加此权限即可:

...
$response->headers->set('Content-length', filesize($zipName));

unlink($zipName);

return $response;

答案 6 :(得分:0)

为我工作。其中$ 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;

答案 7 :(得分:0)

如果仅在[HttpPost("UploadFiles")] public async Task<IActionResult> Post(IFormFile formFile) { //logic throws nullreference at formFile } 函数(例如 console.log($('#fileTest')[0].files[0]); var fd = new FormData(); fd.append('files', $('#fileTest')[0].files[0]); $.ajax({ url: 'https://localhost:44348/api/user/UploadFiles', data: fd, processData: false, contentType: false, type: 'POST', success: function(data){ alert(data);}, error: function (jQXHR, textStatus, errorThrown) { console.log("An error occurred whilst trying to contact the server: " + jQXHR.status + " " + textStatus + " " + errorThrown); } )中指定了名称,ZipArchive会将zip文件创建到您网站的根目录中。指定此函数的路径,例如open。不要忘记使用$zip->open("document.zip", ZipArchive::CREATE)删除此文件(请参见doc)。

这里有一个Symfony 4中的示例(可能适用于早期版本):

$zip->open("my/path/document.zip", ZipArchive::CREATE)

您可能需要将unlink()添加到Composer文件中,才能在use Symfony\Component\HttpFoundation\Response; use \ZipArchive; public function exportAction() { // Do your stuff with $files $zip = new ZipArchive(); $zip_name = "../web/zipFileName.zip"; // Users should not have access to the web folder (it is for temporary files) // Create a zip file in tmp/zipFileName.zip (overwrite if exists) if ($zip->open($zip_name, ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE) { // Add your files into zip foreach ($files as $f) { $zip->addFromString(basename($f), file_get_contents($f)); } $zip->close(); $response = new Response( file_get_contents($zip_name), Response::HTTP_OK, ['Content-Type' => 'application/zip', 'Content-Disposition' => 'attachment; filename="' . basename($zip_name) . '"', 'Content-Length' => filesize($zip_name)]); unlink($zip_name); // Delete file return $response; } else { // Throw an exception or manage the error } } 中使用"ext-zip": "*"ZipArchive

Create a Response object with zip file in Symfony启发的答案。