2017-07-07 4 views
9

Ich habe eine Laravel 5.4 App, wo authentifizierte Benutzer in der Lage sein müssen, private Dateien aus dem S3-Speicher herunterzuladen. Ich habe eine Route und einen Controller eingerichtet, um das Herunterladen von privaten Dateien zu ermöglichen.Laravel 5 Dateidownloads: stream() oder download()

Der Code sieht wie folgt aus:

Route:

Controller:

public function download($fileName) 
{ 
    if (!$fileName || !Storage::exists($fileName)) { 
     abort(404); 
    } 

    return response()->stream(function() use ($fileName) { 
     $stream = Storage::readStream($fileName); 
     fpassthru($stream); 
     if (is_resource($stream)) { 
      fclose($stream); 
     } 
    }, 200, [ 
     'Cache-Control'   => 'must-revalidate, post-check=0, pre-check=0', 
     'Content-Type'   => Storage::mimeType($fileName), 
     'Content-Length'  => Storage::size($fileName), 
     'Content-Disposition' => 'attachment; filename="' . basename($fileName) . '"', 
     'Pragma'    => 'public', 
    ]); 
} 

Alle arbeiten gut, aber wenn ich einen genaueren Blick auf die Laravel docs hatte, fand ich, dass Sie sprechen nur über response()->download().

Wenn ich diese Art von Antwort zu implementieren, würde mein Code wie folgt aussehen:

public function download($fileName) 
{ 
    if (!$fileName || !Storage::exists($fileName)) { 
     abort(404); 
    } 

    $file = Storage::get($fileName); 

    return response()->download($file, $fileName, [ 
     'Content-Type' => Storage::mimeType($fileName), 
    ]); 
} 

Beide Funktionen können im API docs finden.

Meine Frage: Was wäre der bevorzugte Weg zu gehen und was sind die Vorteile/Nachteile von jedem?

Von dem, was ich bisher gesammelt habe:

Stream:

  • erfordert nicht die gesamte Datei
  • Geeignet für große Dateien
in den Speicher geladen werden

Download:

  • Benötigt weniger Code
+0

Vielen Dank dafür! –

+0

@ Jones03 finden Sie unter dieser Antwort https://Stackoverflow.com/a/24008078 – Qh0stM4N

Antwort

1

Wenn Sie Laravel die response() Helfer nennen, ist es eine Instanz der Illuminate\Routing\ResponseFactory zurückgibt. Die ResponseFactory hat diese beiden Methoden: download und stream - die beiden Methoden in Frage. Wenn Sie ein wenig tiefer graben, werden Sie sehen, dass download eine Instanz von \Symfony\Component\HttpFoundation\BinaryFileResponse zurückgibt, während stream eine \Symfony\Component\HttpFoundation\StreamedResponse zurückgibt - das sind beide Symfony-Komponenten.

Es ist nicht notwendig, den Code hier zu durchforsten, aber es ist schön, zu verstehen, was unter der Haube passiert. Jetzt, da wir wissen, dass die zugrunde liegenden Objekte aus der Symfony-HTTP-Komponente stammen, können wir die Symfony-Dokumente konsultieren und sehen, was sie empfehlen. In der Regel werden Streams verwendet, wenn die Größe der Datei unbekannt ist, z. B. wenn Sie die Datei im laufenden Betrieb erstellen. In den meisten anderen Fällen ist die BinaryFileResponse generiert durch die download Methode ausreichend für Ihre Bedürfnisse.

Sie können sich eine ausführlichere Erklärung von HTTP Streaming und seinen Anwendungsfällen here ansehen.