61

ユーザーがダウンロードリンクをクリックしたときにファイルをダウンロードしようとしています。

コントローラの場合:

    $response = new Response();
    $response->headers->set('Content-type', 'application/octect-stream');
    $response->headers->set('Content-Disposition', sprintf('attachment; filename="%s"', $filename));
    $response->headers->set('Content-Length', filesize($filename));

    return $response;

これはファイルを保存するためのダイアログボックスを開いていますが、ファイルは0バイトであると表示されます。そしてそれを次のように変更します:

        $response = new Response();
        $response->headers->set('Content-type', 'application/octect-stream');
        $response->headers->set('Content-Disposition', sprintf('attachment; filename="%s"', $filename));
        $response->headers->set('Content-Length', filesize($filename));
        $response->headers->set('Content-Transfer-Encoding', 'binary');
        $response->setContent(readfile($filename));

        return $response;

ファイルのダウンロードダイアログボックスの代わりに、たくさんの奇妙な文字が表示されます。

最後に、「setContent」行を次のように切り替えます。

    $response->setContent(file_get_contents($filename));

PHPエラーを返します:

致命的なエラー:許可されたメモリサイズ...

これを達成する方法についての手がかりはありますか?私は以前にPHP(MVCなし)でそれを実行しましたが、Symfony2を介してそれを実行するために何が欠けている可能性があるのか​​わかりません...

おそらく解決策はPHP.INIでmemory_limitを設定することですが、それはベストプラクティスではないと思います...

4

7 に答える 7

92

最も快適な解決策は

use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;

$response = new BinaryFileResponse($file);
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT);

return $response;
于 2015-12-03T12:13:07.753 に答える
50

私はついにX-SendFileなしでこれを解決しました(これはおそらくベストプラクティスです)。とにかく、X-Sendfile apacheモジュールを動作させることができない人(共有ホスティング)のために、ここに解決策があります:

// Generate response
$response = new Response();

// Set headers
$response->headers->set('Cache-Control', 'private');
$response->headers->set('Content-type', mime_content_type($filename));
$response->headers->set('Content-Disposition', 'attachment; filename="' . basename($filename) . '";');
$response->headers->set('Content-length', filesize($filename));

// Send headers before outputting anything
$response->sendHeaders();

$response->setContent(file_get_contents($filename));

return $response;
于 2012-10-23T07:19:04.987 に答える
15

PHPはApacheまたはNginxサーバーのタスクであるため、ファイルのダウンロードにPHPを使用しないでください。最適なオプションは、ファイルのダウンロードにX-Accel-Redirect(Nginxの場合)/ X-Sendfile(Apacheの場合)ヘッダーを使用することです。

次のアクションスニペ​​ットを設定済みのNginxで使用して、Symfony2からファイルをダウンロードできます。

return new Response('', 200, array('X-Accel-Redirect' => $filename));

UPD1:mod_xsendfileが構成されたapacheのコード:

return new Response('', 200, array(
    'X-Sendfile'          => $filename,
    'Content-type'        => 'application/octet-stream',
    'Content-Disposition' => sprintf('attachment; filename="%s"', $filename))
);
于 2012-10-22T11:29:05.340 に答える
9

それが役立つかどうかはわかりませんが、そうではapplication/octet-streamありませんapplication/octect-stream

于 2012-10-22T21:13:15.283 に答える
9

Symfony 3.2以降、前の回答で述べたようにを作成するためのショートカットであるfile()コントローラーヘルパーを使用できます。BinaryFileResponse

public function fileAction()
{
    // send the file contents and force the browser to download it
    return $this->file('/path/to/some_file.pdf');
}
于 2017-01-03T14:02:17.340 に答える
6

アレクサンダー応答の+1。

ただし、X-Sendfileを使用できない場合は、2.2で追加されたBinaryFileResponseを使用する必要があります: http ://symfony.com/doc/current/components/http_foundation/introduction.html#serving-files

私のプロジェクトでは、結果は次のとおりです。

$response = new \Symfony\Component\HttpFoundation\BinaryFileResponse($dir .DIRECTORY_SEPARATOR. $zipName);

$d = $response->headers->makeDisposition(
    ResponseHeaderBag::DISPOSITION_ATTACHMENT,
    $zipName
   );

$response->headers->set('Content-Disposition', $d);

return $response;
于 2015-02-04T06:39:16.803 に答える
3

ヘッダーを設定するオプションがない場合:

downloadサポートする必要のあるブラウザによっては、この属性が役立つ場合があります。

<a href="{file url}" download>

また

<a href="{file url}" download="{a different file name}">

これは、すべてのレガシーブラウザでサポートされているわけではありません。ブラウザのサポートについては、次のページを参照してください。

https://www.w3schools.com/tags/att_a_download.asp

于 2017-03-01T19:50:32.970 に答える