2017-07-07 25 views
9

Tôi có ứng dụng Laravel 5.4 nơi người dùng được xác thực cần có thể tải xuống tệp riêng tư từ bộ nhớ S3. Tôi đã thiết lập một tuyến đường và bộ điều khiển để cho phép tải xuống tệp riêng tư.Laravel 5 tải xuống tệp: luồng() hoặc tải xuống()

Mã này trông như thế này:

Route:

Bộ điều khiển:

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', 
    ]); 
} 

Tất cả làm việc tốt, nhưng khi tôi đã có một cái nhìn gần gũi hơn với các Laravel docs, tôi thấy rằng họ chỉ nói về response()->download().

Nếu tôi thực hiện điều đó loại phản ứng, mã của tôi sẽ trông như thế này:

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), 
    ]); 
} 

Cả hai chức năng có thể được tìm thấy trong API docs.

Câu hỏi của tôi: Điều gì sẽ là cách ưa thích để đi và những ưu điểm/nhược điểm của mỗi loại là gì?

Từ những gì tôi đã thu thập được cho đến nay:

Suối:

  • Không yêu cầu toàn bộ tập tin được nạp vào bộ nhớ
  • Thích hợp cho các tập tin lớn

Tải xuống:

  • Yêu cầu mã ít hơn
+0

Cảm ơn bạn vì điều này! –

+0

@ jones03 xem tại câu trả lời này https://stackoverflow.com/a/24008078 – Qh0stM4N

Trả lời

1

Khi bạn gọi Laravel các response() helper, nó sẽ trả về một thể hiện của các Illuminate\Routing\ResponseFactory. Các ResponseFactory có hai phương pháp: downloadstream - hai phương pháp được đề cập. Nếu bạn đào sâu hơn một chút, bạn sẽ thấy rằng download trả về phiên bản \Symfony\Component\HttpFoundation\BinaryFileResponse, trong khi stream trả về một \Symfony\Component\HttpFoundation\StreamedResponse - đây là cả hai thành phần của Symfony.

Đào qua mã ở đây là không cần thiết, nhưng thật tuyệt khi hiểu được những gì đang xảy ra dưới mui xe. Bây giờ chúng ta đã biết các đối tượng cơ bản được trả về là từ Symfony HTTP Component, chúng ta có thể tham khảo các tài liệu của Symfony và xem những gì chúng đề xuất sử dụng. Thông thường, các luồng được sử dụng khi kích thước của tệp không xác định, chẳng hạn như khi bạn tạo tệp ngay lập tức. Trong hầu hết các trường hợp khác, BinaryFileResponse được tạo bởi phương pháp download sẽ đủ cho nhu cầu của bạn.

Bạn có thể xem giải thích sâu hơn về HTTP Streaming và các trường hợp sử dụng HTTP here.