Multipart Upload в Laravel: загрузка больших файлов в S3
Что такое Multipart Upload и зачем он нужен?
Multipart Upload - это метод загрузки больших файлов в S3, при котором файл разбивается на части (чанки) и загружается параллельно. Это решает несколько ключевых проблем:
Надёжность - при обрыве соединения можно перезагрузить только failed-часть
Производительность - параллельная загрузка частей ускоряет процесс
Обход ограничений - позволяет загружать файлы больше 5 ГБ (максимальный размер для простой загрузки)
Как реализовать Multipart Upload в Laravel
1. Установка зависимостей
Убедитесь, что у вас установлен AWS SDK (обычно идёт с Laravel): composer require aws/aws-sdk-php
2. Пример реализации
use Illuminate\Http\UploadedFile; use Aws\S3\MultipartUploader; use Aws\Exception\MultipartUploadException; private function uploadFileToS3(UploadedFile $file, string $fileName): string { // Получаем клиент S3 из Storage фасада $client = Storage::disk('s3')->getClient(); // Путь для сохранения в S3 (можно добавить подпапки по дате и т.д.) $s3Path = $this->s3path.'/'.$fileName; // Настройки загрузчика $uploader = new MultipartUploader($client, $file->getPathname(), [ 'bucket' => config('filesystems.disks.s3.bucket'), 'key' => $s3Path, 'part_size' => 5 * 1024 * 1024, // 5 MB за часть чанка 'concurrency' => 3, // Количество параллельных загрузок 'before_initiate' => function ($command) { // Можно добавить метаданные или ACL $command['ACL'] = 'public-read'; }, 'before_upload' => function ($command) { // Логирование перед загрузкой каждой части Log::info('Uploading part', [ 'part_number' => $command['PartNumber'], 'upload_id' => $command['UploadId'] ); }, ]); try { // Запускаем процесс загрузки $result = $uploader->upload(); // Возвращаем полный путь к файлу в S3 return $s3Path; } catch (MultipartUploadException $e) { // Логируем ошибку Log::error('Multipart upload failed', [ 'file' => $fileName, 'error' => $e->getMessage(), 'upload_id' => $e->getUploadId() ]); // Можно попробовать возобновить загрузку // $this->resumeUpload($e->getUploadId(), $s3Path); throw new \Exception('File upload failed: '.$e->getMessage()); } }
3. Дополнительные методы для работы с Multipart Upload
Возобновление прерванной загрузки
private function resumeUpload(string $uploadId, string $s3Path): string { $client = Storage::disk('s3')->getClient() $uploader = new MultipartUploader($client, null, [ 'bucket' => config('filesystems.disks.s3.bucket'), 'key' => $s3Path, 'upload_id' => $uploadId, 'part_size' => 5 * 1024 * 1024, ]); try { $result = $uploader->upload(); return $s3Path; } catch (MultipartUploadException $e) { throw new \Exception('Resume upload failed: '.$e->getMessage()); } }
Когда использовать Multipart Upload
Файлы больше 100 МБ - для меньших файлов обычная загрузка может быть эффективнее
Ненадёжные соединения - где возможны обрывы
Критичные по времени загрузки - когда нужно максимально ускорить процесс
Оптимизация параметров
part_size:
5-10 MB - хороший баланс для большинства случаев
Увеличивайте для очень больших файлов (>1 GB)
concurrency:
3-5 - оптимально для большинства случаев
Можно увеличить для очень быстрых соединениях
Что ждёт в следующих статьях?
🔹 Ограничения PHP при работе с файлами (максимальный размер загрузки, timeout-ы, memory_limit)
🔹 Глубокий разбор S3 — Versioning, Lifecycle Policies, Cross-Region Replication
🔹 Продвинутое потоковое чтение/запись — обработка гигабайтных логов, CSV и медиа без нагрузки на память
🔹 CDN-оптимизация — Geo-DNS, кеширование, пресеты для изображений
🔹 Секретные фишки — Signed URLs, временные доступы, обработка через очереди
Остались вопросы или есть темы, которые хотите разобрать подробнее? Пишите в комментариях — ваши пожелания станут основой для следующих статей!
