Через тимчасовий підписаний URL для завантаження: сервер лише видає дозвіл, а файл іде з браузера чи мобільного застосунку напряму в сховище.
public function store(Request $request): JsonResponse
{
$path = 'uploads/'.$request->user()->id.'/'.Str::uuid().'.mp4';
['url' => $url, 'headers' => $headers] = Storage::disk('s3')->temporaryUploadUrl(
$path, now()->plus(minutes: 10),
);
return response()->json(compact('url', 'headers', 'path'));
}
Клієнт робить PUT на url з headers, потім повідомляє застосунку path.
Чому це краще за завантаження через PHP:
- великий файл не займає воркер PHP і не впирається в
upload_max_filesize,post_max_sizeі таймаути; - немає подвійного трафіку «клієнт → сервер → S3».
Що контролює сервер:
- шлях генерує сам (а не приймає від клієнта) - користувач пише лише у свою теку;
- короткий термін дії URL;
- після завантаження - перевірка: файл існує, розмір і тип відповідають очікуванням (
Storage::size(),mimeType()), лише тоді запис у базі; - незавершені завантаження прибирає правило життєвого циклу бакета.
Підтримують драйвери s3 і local. Для перегляду приватних файлів - temporaryUrl().