2013-03-05 3 views
17

Я пытаюсь сделать принудительное скачивание с использованием ZF2. Вот фрагмент кода, чтобы мой кодforce download using 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\"")); 


} 

теперь я получаю эту ошибку

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

Сообщение:

A valid request line was not found in the provided string 

Стек след:

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

Вместо инстанцирования нового объекта запроса вы должны получить существующий ответ. Попробуйте $ this-> getResponse(); после того, как вы установили заголовки, вы должны вернуть ответ. –

+0

Единственными причинами, по которым я не использовал существующие заголовки, было то, что у существующих заголовков не было контента, который я хотел, поэтому мне пришлось создавать новые. –

ответ

36

Этот код должен помочь вы для простой загрузки файла.

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

Я представляю себе этот код оставляет желать лучшего, но должны работать в простых случаях, как это было мое. Я не уверен, как вы можете обрабатывать файл в кусках. Может, кто-то еще мог пролить свет?

Edit - Отправка потоков

Я добавил это здесь в информационных целях. Вероятно, это лучший способ заставить загружать файлы, поскольку он будет использовать гораздо меньше памяти.

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

Спасибо @Aydin Hassan за ответ, но в его ответе отсутствуют несколько важных заголовков. Будьте осторожны.

полных заголовков стек:

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

Согласен. Но вы должны учитывать тот факт, что этот вопрос задавали около 2 лет назад и в соответствии с необходимостью того времени и зрелости ZF2 в то время, этот вопрос и ответ на него решали многие проблемы базового уровня –

+3

@ noobie- php У вас есть моя гарантия, что спецификация HTTP не меняется в течение этих двух лет. Я стараюсь улучшить контент сообщества SO и добавить некоторые заголовки. Это headrs предотвращает возможное кэширование загрузки содержимого, зависит от реализации браузера. Спасибо за заданный вопрос, ответ на этот вопрос (после нескольких исследований) позволил решить мою проблему быстрее. – Athlan