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

Як працювати з великими файлами, не вичерпуючи пам'ять?

Головне правило - не тримати файл цілком у пам'яті PHP. Storage::get() на файлі в 2 ГБ упреться в memory_limit.

Запис потоком:

Storage::disk('s3')->putFile('videos', $request->file('video'));   // потоком, а не get/put
Storage::disk('s3')->writeStream('backup.sql.gz', fopen($path, 'r'));

putFile() і putFileAs() передають файл потоком самі.

Читання потоком:

$stream = Storage::disk('s3')->readStream('exports/big.csv');
while (($line = fgets($stream)) !== false) { /* ... */ }

Віддача користувачу:

// згенерований на льоту файл - без запису на диск
return response()->streamDownload(function () {
    $out = fopen('php://output', 'w');
    Order::query()->lazyById(1000)->each(fn ($o) => fputcsv($out, [$o->id, $o->total]));
    fclose($out);
}, 'orders.csv');

// готовий файл у S3 - краще посилання, ніж проксі через PHP
return redirect(Storage::disk('s3')->temporaryUrl($path, now()->plus(minutes: 5)));

Що ще допомагає:

  • важку обробку (конвертація відео, архівування) - у чергу, з окремим воркером і більшим таймаутом;
  • завантаження великих файлів від клієнтів - напряму в сховище (temporaryUploadUrl());
  • для local у Nginx - X-Accel-Redirect, щоб файл віддавав вебсервер, а PHP лише перевіряв права.

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

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

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