2013-03-05 22 views
17

Sto cercando di eseguire il download forzato utilizzando ZF2. Ecco il frammento di al mio codicedownload forzato tramite ZF2

use Zend\Http\Request; 
..... 
    public function downloadAction() { 
    $response = new Request(); 
    $response->setHeaders(Request::fromString("Content-Type: application/octet-stream\r\nContent-Length: 9\r\nContent-Disposition: attachment; filename=\"ultimate_remedy_readme.txt\"")); 


} 

ora sto ottenendo questo errore

/var/www/whowantsmymoney/vendor/zendframework/zendframework/library/Zend/Http/Request.php:88 

Messaggio:

A valid request line was not found in the provided string 

traccia stack:

#0 /var/www/whowantsmymoney/module/Admin/src/Admin/Controller/LanguageController.php(93): Zend\Http\Request::fromString('Content-Type: a...') 
+0

Invece di istanziare un nuovo oggetto di richiesta si dovrebbe ottenere la risposta esistente. Prova $ this-> getResponse(); dopo aver impostato le intestazioni, è necessario restituire la risposta. –

+0

l'unico motivo per cui non stavo usando le intestazioni esistenti era che le intestazioni esistenti non avevano contenuto che desideravo quindi dovevo creare nuovo. –

risposta

36

Tale codice dovrebbe aiutare per un semplice download di file.

public function downloadAction() { 
    $fileName = 'somefile'; 

    if(!is_file($fileName)) { 
     //do something 
    } 

    $fileContents = file_get_contents($fileName); 

    $response = $this->getResponse(); 
    $response->setContent($fileContents); 

    $headers = $response->getHeaders(); 
    $headers->clearHeaders() 
     ->addHeaderLine('Content-Type', 'whatever your content type is') 
     ->addHeaderLine('Content-Disposition', 'attachment; filename="' . $fileName . '"') 
     ->addHeaderLine('Content-Length', strlen($fileContents)); 


    return $this->response; 
} 

immagino che questo codice lascia molto a desiderare, ma dovrebbe funzionare nei casi più semplici, come era la mia. Non sono sicuro di come potresti gestire la lettura del file in blocchi. Forse qualcun altro potrebbe far luce?

Modifica - L'invio di flussi

Ho aggiunto questa qui a scopo informativo. È probabilmente il modo migliore per forzare i download poiché utilizzerà molta meno memoria.

public function downloadAction() { 
    $fileName = 'somefile'; 

    $response = new \Zend\Http\Response\Stream(); 
    $response->setStream(fopen($fileName, 'r')); 
    $response->setStatusCode(200); 

    $headers = new \Zend\Http\Headers(); 
    $headers->addHeaderLine('Content-Type', 'whatever your content type is') 
      ->addHeaderLine('Content-Disposition', 'attachment; filename="' . $fileName . '"') 
      ->addHeaderLine('Content-Length', filesize($fileName)); 

    $response->setHeaders($headers); 
    return $response; 
5

Grazie a @Aydin Hassan per la risposta, ma nella sua risposta mancano alcuni importanti intestazioni. Stai attento a questo.

intestazioni stack completo:

public function downloadAction() { 
    $file = 'path/to/file'; 
    $response = new \Zend\Http\Response\Stream(); 
    $response->setStream(fopen($file, 'r')); 
    $response->setStatusCode(200); 
    $response->setStreamName(basename($file)); 
    $headers = new \Zend\Http\Headers(); 
    $headers->addHeaders(array(
     'Content-Disposition' => 'attachment; filename="' . basename($file) .'"', 
     'Content-Type' => 'application/octet-stream', 
     'Content-Length' => filesize($file), 
     'Expires' => '@0', // @0, because zf2 parses date as string to \DateTime() object 
     'Cache-Control' => 'must-revalidate', 
     'Pragma' => 'public' 
    )); 
    $response->setHeaders($headers); 
    return $response; 
} 
+0

D'accordo.Ma si dovrebbe considerare il fatto, che questa domanda è stata posta circa 2 anni fa e in base alla necessità di quel tempo e la maturità di ZF2 in quel momento, questa domanda e la sua risposta risolti molti problemi di livello base –

+3

@ noobie- php Hai la mia garanzia, che le specifiche HTTP non sono cambiate durante questi 2 anni. Mi sforzo di migliorare il contenuto della community SO e ho aggiunto alcune intestazioni. Il fatto che le intestazioni impediscano l'eventuale memorizzazione del contenuto nella cache, dipende dall'implementazione del browser. Grazie per la domanda fatta, la risposta per questo (dopo qualche ricerca in più) ha risolto il mio problema più velocemente. – Athlan