2013-11-28 2 views
10

Ich habe eine Anwendung, die einige Dateien hochladen und dann kann ich als Zip-Datei komprimieren und herunterladen.Symfony2 Zip-Datei erstellen und herunterladen

Die Export Aktion:

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

alles in Ordnung ist, bis der Zeilenkopf. und jedes Mal, wenn ich hier bin, habe ich den Fehler: "Warnung: readfile (../web/Documents-1385648213.zip): Fehler beim Öffnen Stream: Keine solche Datei oder Verzeichnis"

Was ist los?

und warum, wenn ich die Dateien hochladen, haben diese Dateien Root-Berechtigungen, und das gleiche passiert für die ZIP-Datei, die ich erstelle.

Antwort

7

gelöst:

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

offenbar Schließen der Datei wichtig ist;)

+0

-Controller benötigt zurückzukehren, um eine Antwort. Die letzte Zeile sollte '' 'return new sein Antwort (readfile ($ zipName));' ' – jdewit

+0

readfile() gibt keinen String zurück, der in eine Antwort eingefügt werden kann. Sie müssen dafür eine Streaming-Antwort verwenden oder file_get_contents verwenden. –

0

Ich denke, es ist besser, dass Sie

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

mit der post-Variable Ihrer ID Zip verwenden = ' zipFiles '. Es ist besser alle $ _POST Variablen zu holen.

6

SYMFONY 3 Beispiel nützlich sein:

public function zipDownloadAllDocumentAction($documents) 
{ 
    $files = array(); 
    $em = $this->getDoctrine()->getManager(); 

    foreach ($documents as $d) { 
     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)); 
    } 
    $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)); 

    return $response; 
}