Renê Lima
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
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:

1
2
#[MapUploadedFile(new Assert\File(mimeTypes: ['application/pdf']))]
UploadedFile ...$documents
Published in #Living on the edge