Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як віддати користувачу файл у Laravel: download, file і streamDownload?

Три методи для трьох ситуацій:

1. download - завантажити файл, що вже є на диску:

return response()->download(storage_path('app/reports/2026-q3.pdf'));
return response()->download($path, 'Звіт за III квартал.pdf');   // інша назва для користувача
return response()->download($path)->deleteFileAfterSend();      // тимчасовий файл

Заголовок Content-Disposition: attachment - браузер пропонує зберегти файл.

2. file - показати файл у браузері (зображення, PDF):

return response()->file(storage_path('app/invoices/42.pdf'));

Content-Disposition: inline - PDF відкриється у вбудованому переглядачі.

3. streamDownload - файл, якого немає на диску, генерується на льоту:

return response()->streamDownload(function () {
    $out = fopen('php://output', 'w');
    fputcsv($out, ['id', 'email']);

    User::query()->lazyById(1000)->each(function (User $user) use ($out) {
        fputcsv($out, [$user->id, $user->email]);
    });

    fclose($out);
}, 'users.csv', ['Content-Type' => 'text/csv']);

Дані віддаються частинами - експорт мільйона рядків не займає мільйона рядків пам'яті й не створює тимчасових файлів.

З дисків Storage (зокрема S3):

return Storage::download('reports/2026-q3.pdf', 'report.pdf');
return Storage::disk('s3')->response('avatars/42.jpg');   // показати

Безпека - головне при віддачі файлів:

  • шлях ніколи не будується з введення користувача напряму: download(storage_path('app/' . $request->file)) дозволить завантажити ../../.env (обхід шляху). Файл шукають за ідентифікатором у базі, де записано шлях;
  • перевірка прав перед віддачею - політика чи Gate, як для будь-якого ресурсу;
  • приватні файли не кладуть у public/ чи публічний диск - вони мають віддаватися лише через контролер з перевіркою;
  • назва файлу від користувача - через download($path, $safeName), Laravel сам коректно закодує не-ASCII символи в заголовку.

Для великих файлів на S3 краще не проганяти їх через PHP взагалі: тимчасове підписане посилання Storage::temporaryUrl() - і браузер завантажує прямо зі сховища.

Докладніше в документації: Відповіді: завантаження файлів

Схожі питання