Skip to content

Commit 92e3c92

Browse files
committed
Update file-upload.md
Added part about serialization when using a file upload with the User entity, which gets serialized by Symfony for the session.
1 parent fea624e commit 92e3c92

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed

symfony/file-upload.md

+67
Original file line numberDiff line numberDiff line change
@@ -490,3 +490,70 @@ final class UploadedFileDenormalizer implements DenormalizerInterface
490490
If you're not using `autowiring` and `autoconfiguring`, don't forget to register the service and tag it as `serializer.normalizer`.
491491

492492
For resolving the file URL, you can use a custom normalizer, like shown in [the previous example](#resolving-the-file-url).
493+
494+
### Uploading Files on your User Entity
495+
496+
If you’d like to add file-upload support directly to your `User` entity (rather than a dedicated `MediaObject`), there’s one extra “gotcha” you may have to take care of.
497+
498+
> [!NOTE]
499+
> If you only expose file uploads through API Platform’s endpoints (e.g. POST /media_objects or POST /users/{id}/avatar), you don’t need any special serialization hooks and you can ignore this part.
500+
> This part is only relevant if you try to attach an `UploadedFile` or `File` object directly to your `User` entity in a non-API context (for example via a Symfony form controller where the `User` is stored in the session).
501+
502+
Symfony’s session handler will attempt to serialize the entire `User` object when it stores your `User` in the session (for example via the Security token in a Symfony form controller).
503+
Since `File` is not serializable by default, you’ll encounter:
504+
```
505+
Serialization of 'Symfony\Component\HttpFoundation\File\File' is not allowed
506+
```
507+
508+
To fix this, you need to implement both the old `\Serializable` interface **and**, starting with PHP 7.4+, the new `__serialize()` / `__unserialize()` magic methods on your `User`, limiting serialization to just scalar fields (`id`, `email`, `password`, etc.).
509+
Symfony will then happily keep your `User` in the session while VichUploaderBundle handles the file itself.
510+
511+
```php
512+
#[Vich\Uploadable]
513+
#[ORM\Entity]
514+
#[ApiResource(...)]
515+
class User implements UserInterface, PasswordAuthenticatedUserInterface, \Serializable
516+
{
517+
private ?Uuid $id;
518+
private ?string $email;
519+
private ?string $password;
520+
521+
// …
522+
523+
// Legacy Serializable, still used by Symfony SessionStorage
524+
public function serialize(): string
525+
{
526+
return serialize([
527+
(string) $this->id,
528+
$this->email,
529+
$this->password,
530+
]);
531+
}
532+
533+
public function unserialize(string $data): void
534+
{
535+
list(
536+
$this->id,
537+
$this->email,
538+
$this->password,
539+
) = unserialize($data);
540+
}
541+
542+
// PHP 7.4+ Magic Methods
543+
public function __serialize(): array
544+
{
545+
return [
546+
'id' => (string) $this->id,
547+
'email' => $this->email,
548+
'password' => $this->password,
549+
];
550+
}
551+
552+
public function __unserialize(array $data): void
553+
{
554+
$this->id = Uuid::fromString($data['id']);
555+
$this->email = $data['email'];
556+
$this->password = $data['password'];
557+
}
558+
}
559+
```

0 commit comments

Comments
 (0)