How to Access Services or Config from Inside a Form
Warning: You are browsing the documentation for Symfony 2.x, which is no longer maintained.
Read the updated version of this page for Symfony 7.1 (the current stable version).
Sometimes, you may need to access a service or other configuration from inside of your form class. To do this, you have 2 options:
1) Pass Options to your Form
The simplest way to pass services or configuration to your form is via form options.
Suppose you need to access the doctrine.orm.entity_manager
service so that you
can make a query. First, allow (in fact, require) a new entity_manager
option
to be passed to your form:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// src/AppBundle/Form/TaskType.php
// ...
class TaskType extends AbstractType
{
// ...
public function configureOptions(OptionsResolver $resolver)
{
// ...
$resolver->setRequired('entity_manager');
}
}
Now that you've done this, you must pass an entity_manager
option when you
create your form:
1 2 3 4 5 6 7 8 9 10 11 12 13
// src/AppBundle/Controller/DefaultController.php
use AppBundle\Form\TaskType;
// ...
public function newAction()
{
$task = ...;
$form = $this->createForm(TaskType::class, $task, array(
'entity_manager' => $this->get('doctrine.orm.entity_manager'),
));
// ...
}
Finally, the entity_manager
option is accessible in the $options
argument
of your buildForm()
method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// src/AppBundle/Form/TaskType.php
// ...
class TaskType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
/** @var \Doctrine\ORM\EntityManager $entityManager */
$entityManager = $options['entity_manager'];
// ...
}
// ...
}
Use this method to pass anything to your form.
2) Define your Form as a Service
Alternatively, you can define your form class as a service. This is a good idea if you want to re-use the form in several places - registering it as a service makes this easier.
Suppose you need to access the doctrine.orm.entity_manager
service so that you
can make a query. First, add this as an argument to your form class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// src/AppBundle/Form/TaskType.php
use Doctrine\ORM\EntityManager;
// ...
class TaskType extends AbstractType
{
private $entityManager;
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
// ...
}
Next, register this as a service and tag it with form.type
:
1 2 3 4 5 6 7
# src/AppBundle/Resources/config/services.yml
services:
app.form.type.task:
class: AppBundle\Form\TaskType
arguments: ['@doctrine.orm.entity_manager']
tags:
- { name: form.type }
That's it! Your controller - where you create the form - doesn't need to change
at all: Symfony is smart enough to load the TaskType
from the container.
Read How to Create a Custom Form Field Type for more information.