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 МБ - для меньших файлов обычная загрузка может быть эффективнее
Ненадёжные соединения - где возможны обрывы
Критичные по времени загрузки - когда нужно максимально ускорить процесс
Оптимизация параметров
Что ждёт в следующих статьях?
🔹 Ограничения PHP при работе с файлами (максимальный размер загрузки, timeout-ы, memory_limit)
🔹 Глубокий разбор S3 — Versioning, Lifecycle Policies, Cross-Region Replication
🔹 Продвинутое потоковое чтение/запись — обработка гигабайтных логов, CSV и медиа без нагрузки на память
🔹 CDN-оптимизация — Geo-DNS, кеширование, пресеты для изображений
🔹 Секретные фишки — Signed URLs, временные доступы, обработка через очереди
Остались вопросы или есть темы, которые хотите разобрать подробнее? Пишите в комментариях — ваши пожелания станут основой для следующих статей!