New in Symfony 7.1: MapUploadedFile Attribute


Contributed by RenĂª Lima
in #49978.

In Symfony 6.3 we introduced a way to map Request data to typed objects. We've
improved and expanded that feature in the following versions and that's why in
Symfony 7.1 we're introducing a new #[MapUploadedFile] attribute to
map uploaded files to controller arguments.
The following example shows the simplest use case, where the attribute is applied
(without any options) to some controller argument to tell Symfony to inject an
UploadedFile object in it:

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\MapUploadedFile;
use Symfony\Component\Routing\Attribute\Route;

class UserController extends AbstractController
{
// ...

#[Route('/user/picture', methods: ['PUT'])]
public function changeUserPicture(
#[MapUploadedFile] UploadedFile $picture,
): Response
{
// ...
}
}

A common need when uploading files is to validate the file types and other file
characteristics such as its dimensions. The #[MapUploadedFile] attribute allows
to pass a list of constraints to apply to the file:

use Symfony\Component\Validator\Constraints as Assert;
// ...

#[Route('/user/picture', methods: ['PUT'])]
public function changeUserPicture(
#[MapUploadedFile([
new Assert\File(mimeTypes: ['image/png', 'image/jpeg']),
new Assert\Image(maxWidth: 3840, maxHeight: 2160)
])]
UploadedFile $picture
): Response {
// ...
}

The given constraints are checked before injecting the UploadedFile into the
controller argument. If there's any constraint violation, an HttpException is
thrown and the controller's action is not executed.
Lastly, you can inject a collection of files by using a variadic argument:

#[MapUploadedFile(new Assert\File(mimeTypes: ['application/pdf']))]
UploadedFile ...$documents

Sponsor the Symfony project.