2013-11-28 18 views
10

Ho un'applicazione che carica alcuni file e quindi posso comprimere come file zip e scaricare.Symfony2 crea e scarica il file zip

L'azione di esportazione:

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

tutto è ok fino a quando l'intestazione di linea. e ogni volta che vado qui ho ricevuto l'errore: "Avviso: readfile (../ web/Documenti-1385648213.zip): impossibile aprire lo stream: Nessun file o directory"

Cosa c'è che non va?

e perché quando carico i file, questi file hanno i permessi di root e lo stesso accade per il file zip che creo.

risposta

7

risolto:

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

a quanto pare la chiusura del file è importante;)

+0

controller deve restituire una risposta. L'ultima riga dovrebbe essere '' 'return new Response (readfile ($ zipName));' '' – jdewit

+0

readfile() non restituisce una stringa che può essere inserita in una risposta. È necessario utilizzare una risposta di streaming per quello o utilizzare file_get_contents –

0

penso è meglio utilizzare

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

con la variabile postale del vostro id zip = ' zipfiles'. È meglio recuperare tutte le variabili $ _POST.

6

SYMFONY 3 esempio:

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