VichUploaderBundle reference
28 November 2022 (Updated 10 February 2024)
In a nutshell
VichUploaderBundle is a Symfony bundle that provides an easy way to link file uploads with ORM entities or MongoDB ODM documents.
Its features include:
- Set the file in the entity as an instance of
Symfony\Component\HttpFoundation\File\File
when the entity is loaded from the datastore. - Delete the file from the file system when the entity/document is removed from the datastore.
- Templating helpers to generate public URLs to the file.
Usage
1. Install and register bundle
Install package:
composer require vich/uploader-bundle
Register (if not using Symfony Flex):
// app/AppKernel.php (your kernel class may be defined in a different class/path)
class AppKernel extends Kernel
{
public function registerBundles()
{
$bundles = [
// ...
new Vich\UploaderBundle\VichUploaderBundle(),
// ...
];
}
}
2. Configure persistence engine
# config/packages/vich_uploader.yaml or app/config/config.yml
vich_uploader:
db_driver: orm # or mongodb or phpcr
3. Configure an upload mapping
# config/packages/vich_uploader.yaml or app/config/config.yml
vich_uploader:
db_driver: orm
metadata:
type: attribute
mappings:
products:
uri_prefix: /images/products
upload_destination: '%kernel.project_dir%/public/images/products'
namer: Vich\UploaderBundle\Naming\SmartUniqueNamer
You need to define three things as a minimum:
<mapping-name>
:products
in the above example.uri_prefix
: The public web path to the upload destination – the URL that users will be able to access files from.upload_destination
: The location on the server the files should be uploaded.
4. Link the upload mapping to an entity
Create a link between the filesystem and an entity by adding an Uploadable
annotation to an entity. This is like a flag that tells the bundle that a given entity contains uploadable fields.
Next, add two fields:
- Create a persistent field (e.g.,
imageName
) that will be stored in the database as a string. This will contain the filename of the uploaded file. - Create a non-persistent (e.g.,
imageFile
) that will store theUploadedFile
object after the form is submitted. This shouldn’t be persisted in the database, but you must annotate it.
Here’s an example entity that contains all the above:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
#[ORM\Entity]
#[Vich\Uploadable]
class Product
{
#[ORM\Id]
#[ORM\Column(type: 'integer')]
#[ORM\GeneratedValue(strategy: 'AUTO')]
private ?int $id = null;
// ... other fields
// Path to file stored in "<mapping>.storage"
#[ORM\Column(nullable: true)]
private ?string $imageFilePath = null;
// NOTE: This is not a mapped field of entity metadata, just a simple property.
#[Vich\UploadableField(mapping: 'products', fileNameProperty: 'imageName', size: 'imageSize')]
private ?File $imageFile = null;
// Auxiliary property to handle base64 encoded uploads on JSON requests
private ?string $imageFileBase64 = null;
#[ORM\Column(type: 'string')]
private ?string $imageName = null;
#[ORM\Column(type: 'integer')]
private ?int $imageSize = null;
#[ORM\Column(type: 'datetime')]
private ?\DateTimeInterface $updatedAt = null;
/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*
* @param File|\Symfony\Component\HttpFoundation\File\UploadedFile|null $imageFile
*/
public function setImageFile(?File $imageFile = null): void
{
$this->imageFile = $imageFile;
if (null !== $imageFile) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->updatedAt = new \DateTimeImmutable();
}
}
public function getImageFile(): ?File
{
return $this->imageFile;
}
public function setImageName(?string $imageName): void
{
$this->imageName = $imageName;
}
public function getImageName(): ?string
{
return $this->imageName;
}
public function setImageSize(?int $imageSize): void
{
$this->imageSize = $imageSize;
}
public function getImageSize(): ?int
{
return $this->imageSize;
}
}
5. Configure the lifecycle events (optional)
You can configure when files should be removed using the below configuration options:
# config/packages/vich_uploader.yaml or app/config/config.yml
vich_uploader:
db_driver: orm
mappings:
products:
uri_prefix: /images/products
upload_destination: '%kernel.project_dir%/public/images/products'
namer: Vich\UploaderBundle\Naming\SmartUniqueNamer
inject_on_load: false
delete_on_update: true
delete_on_remove: true
delete_on_remove
: defaulttrue
, should the file be deleted when the entity is removed ;delete_on_update
: defaulttrue
, should the file be deleted when a new file is uploaded ;inject_on_load
: defaultfalse
, should the file be injected into the uploadable entity when it is loaded from the data store. The object will be an instance ofSymfony\Component\HttpFoundation\File\File
.
Other notes
- Configuration is usually at
config/packages/vich_uploader.yaml
. - You can use helper functions generate public URLs
Sources
Tagged:
Symfony
Thanks for your comment 🙏. Once it's approved, it will appear here.
Leave a comment