Мы продолжаем наш курс по Symfony для начинающих. В 13-ом уроке разберем одну из тем, это работу с файлами. Вы научитесь загружать файлы через формы, сохранять их в облаке, генерировать превью изображений и многое другое.
Загрузка файлов через формы
Загрузка файлов частая задача веб-приложений. В Symfony это делается через форму с использованием компонента Form. Вот как это работает:
Шаг 1: Создание формы
Добавим поле для загрузки файла в форму. Для этого используем тип FileType:
// src/Form/UploadFileType.php namespace App\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\Extension\Core\Type\FileType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; class UploadFileType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('file', FileType::class, [ 'label' => 'Выберите файл', ]) ->add('save', SubmitType::class, [ 'label' => 'Загрузить', ]); } }
Шаг 2: Отображение формы в шаблоне
Важно не забыть добавить атрибут enctype="multipart/form-data" в форму, иначе файл не отправится:
{# templates/upload/index.html.twig #} {{ form_start(form, {'attr': {'enctype': 'multipart/form-data'}}) }} {{ form_widget(form) }} {{ form_end(form) }}
Шаг 3: Обработка загрузки в контроллере
Получим загруженный файл через объект UploadedFile:
// src/Controller/UploadController.php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use App\Form\UploadFileType; class UploadController extends AbstractController { public function upload(Request $request): Response { $form = $this->createForm(UploadFileType::class); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $file = $form->get('file')->getData(); // Здесь будем обрабатывать файл return $this->redirectToRoute('upload_success'); } return $this->render('upload/index.html.twig', [ 'form' => $form->createView(), ]); } }
Использование UploadedFile
Объект UploadedFile предоставляет методы для работы с загруженным файлом. Например:
Валидация файла
Проверим размер и MIME-тип:
if ($file) { // Максимальный размер файла 5 МБ $maxSize = 5 * 1024 * 1024; if ($file->getSize() > $maxSize) { throw new \Exception('Файл слишком большой!'); } // Допустимые MIME-типы $allowedMimeTypes = ['image/jpeg', 'image/png', 'application/pdf']; if (!in_array($file->getMimeType(), $allowedMimeTypes)) { throw new \Exception('Недопустимый формат файла!'); } }
Сохранение файла
Переместим файл в директорию public/uploads:
$fileName = uniqid().'.'.$file->guessExtension(); $file->move( $this->getParameter('upload_directory'), // путь задан в services.yaml $fileName );
Не забудьте добавить параметр в config/services.yaml:
parameters: upload_directory: '%kernel.project_dir%/public/uploads'
Хранение файлов в облаке (Amazon S3, Google Cloud)
Хранить файлы локально, не всегда лучший вариант. Для облачного хранения используем Flysystem:
Установка Flysystem
Подключим бандл для работы с облачными провайдерами:
composer require league/flysystem-bundle
Настройка Amazon S3
Добавим конфигурацию в .env:
AWS_ACCESS_KEY_ID=ваш_ключ AWS_SECRET_ACCESS_KEY=ваш_секрет AWS_BUCKET_NAME=имя_бакета
Настроим Flysystem в config/packages/flysystem.yaml:
flysystem: storages: s3_storage: adapter: 'aws' options: client: Aws\S3\S3Client bucket: '%env(AWS_BUCKET_NAME)%'
Загрузка файла в S3
Используем сервис s3_storage:
use League\Flysystem\Filesystem; public function uploadToS3(Filesystem $s3Storage, UploadedFile $file) { $stream = fopen($file->getRealPath(), 'r'); $s3Storage->writeStream( 'uploads/'.$file->getClientOriginalName(), $stream ); fclose($stream); }
Генерация превью изображений
Для работы с изображениями установим Imagine Bundle:
composer require liip/imagine-bundle
Создание превью
Изменим размер изображения до 200×200 пикселей:
use Liip\ImagineBundle\Imagine\Cache\CacheManager; public function generateThumbnail(CacheManager $cacheManager, string $imagePath) { // Путь к оригинальному изображению $fullPath = $this->getParameter('upload_directory').'/'.$imagePath; // Генерируем превью $thumbnailPath = $cacheManager->getBrowserPath($imagePath, 'my_thumb'); return $thumbnailPath; }
Настроим фильтр в config/packages/liip_imagine.yaml:
liip_imagine: filter_sets: my_thumb: quality: 80 filters: thumbnail: { size: [200, 200], mode: outbound }
Практические задачи
- Задача 1: Создайте форму для загрузки аватара пользователя.
Решение: Добавьте полеavatarтипаFileTypeв форму регистрации. - Задача 2: Реализуйте загрузку файлов в Google Cloud Storage.
Подсказка: Используйте адаптерgoogleв Flysystem. - Задача 3: Сгенерируйте превью для загруженного изображения и сохраните его в облако.
Пример: После загрузки изображения вызовитеgenerateThumbnail()и сохраните результат в S3.
Сегодня вы освоили работу с файлами в Symfony, от загрузки через формы до хранения в облаке. Это важный навык для создания современных веб-приложений. Если что-то осталось непонятным, пишите вопросы в комментариях.
Хотите продолжить обучение? Переходите к полному курсу по Symfony для начинающих. Жду вас на следующем уроке.
Поддержка автора осуществляется с помощью специальной формы ниже, предоставленной сервисом «ЮMoney». Все платёжные операции выполняются на защищённой странице сервиса, что обеспечивает их корректность и полную безопасность.


