|
1 | 1 | How to Access Services or Config from Inside a Form
|
2 | 2 | ===================================================
|
3 | 3 |
|
4 |
| -Sometimes, you may need to access a :doc:`service </service_container>` or other |
5 |
| -configuration from inside of your form class. To do this, you have 2 options: |
6 |
| - |
7 |
| -1) Pass Options to your Form |
8 |
| ----------------------------- |
9 |
| - |
10 |
| -The simplest way to pass services or configuration to your form is via form *options*. |
11 |
| -Suppose you need to access the Doctrine entity manager so that you can make a |
12 |
| -query. First, allow (in fact, require) a new ``entity_manager`` option to be |
13 |
| -passed to your form:: |
14 |
| - |
15 |
| - // src/Form/TaskType.php |
16 |
| - // ... |
17 |
| - |
18 |
| - class TaskType extends AbstractType |
19 |
| - { |
20 |
| - // ... |
21 |
| - |
22 |
| - public function configureOptions(OptionsResolver $resolver) |
23 |
| - { |
24 |
| - // ... |
25 |
| - |
26 |
| - $resolver->setRequired('entity_manager'); |
27 |
| - } |
28 |
| - } |
29 |
| - |
30 |
| -Now that you've done this, you *must* pass an ``entity_manager`` option when you |
31 |
| -create your form:: |
32 |
| - |
33 |
| - // src/Controller/DefaultController.php |
34 |
| - use App\Form\TaskType; |
35 |
| - |
36 |
| - // ... |
37 |
| - public function new() |
38 |
| - { |
39 |
| - $entityManager = $this->getDoctrine()->getManager(); |
40 |
| - |
41 |
| - $task = ...; |
42 |
| - $form = $this->createForm(TaskType::class, $task, [ |
43 |
| - 'entity_manager' => $entityManager, |
44 |
| - ]); |
45 |
| - |
46 |
| - // ... |
47 |
| - } |
48 |
| - |
49 |
| -Finally, the ``entity_manager`` option is accessible in the ``$options`` argument |
50 |
| -of your ``buildForm()`` method:: |
51 |
| - |
52 |
| - // src/Form/TaskType.php |
53 |
| - // ... |
54 |
| - |
55 |
| - class TaskType extends AbstractType |
56 |
| - { |
57 |
| - public function buildForm(FormBuilderInterface $builder, array $options) |
58 |
| - { |
59 |
| - /** @var \Doctrine\ORM\EntityManager $entityManager */ |
60 |
| - $entityManager = $options['entity_manager']; |
61 |
| - // ... |
62 |
| - } |
63 |
| - |
64 |
| - // ... |
65 |
| - } |
66 |
| - |
67 |
| -Use this method to pass *anything* to your form. |
68 |
| - |
69 |
| -2) Define your Form as a Service |
70 |
| --------------------------------- |
71 |
| - |
72 |
| -Alternatively, you can define your form class as a service. This is a good idea if |
73 |
| -you want to re-use the form in several places - registering it as a service makes |
74 |
| -this easier. |
75 |
| - |
76 |
| -Suppose you need to access the :ref:`EntityManager <doctrine-entity-manager>` object |
77 |
| -so that you can make a query. First, add this as an argument to your form class:: |
78 |
| - |
79 |
| - // src/Form/TaskType.php |
80 |
| - use Doctrine\ORM\EntityManagerInterface; |
81 |
| - // ... |
82 |
| - |
83 |
| - class TaskType extends AbstractType |
84 |
| - { |
85 |
| - private $entityManager; |
86 |
| - |
87 |
| - public function __construct(EntityManagerInterface $entityManager) |
88 |
| - { |
89 |
| - $this->entityManager = $entityManager; |
90 |
| - } |
91 |
| - |
92 |
| - // ... |
93 |
| - } |
94 |
| - |
95 |
| -If you're using :ref:`autowire <services-autowire>` and |
96 |
| -:ref:`autoconfigure <services-autoconfigure>`, then you don't need to do *anything* |
97 |
| -else: Symfony will automatically know how to pass the correct ``EntityManager`` object |
98 |
| -to your ``__construct()`` method. |
99 |
| - |
100 |
| -If you are **not using autowire and autoconfigure**, register your form as a service |
101 |
| -manually and tag it with ``form.type``: |
102 |
| - |
103 |
| -.. configuration-block:: |
104 |
| - |
105 |
| - .. code-block:: yaml |
106 |
| -
|
107 |
| - # config/services.yaml |
108 |
| - services: |
109 |
| - App\Form\TaskType: |
110 |
| - arguments: ['@doctrine.orm.entity_manager'] |
111 |
| - tags: [form.type] |
112 |
| -
|
113 |
| - .. code-block:: xml |
114 |
| -
|
115 |
| - <!-- config/services.xml --> |
116 |
| - <?xml version="1.0" encoding="UTF-8" ?> |
117 |
| - <container xmlns="http://symfony.com/schema/dic/services" |
118 |
| - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
119 |
| - xsi:schemaLocation="http://symfony.com/schema/dic/services |
120 |
| - https://symfony.com/schema/dic/services/services-1.0.xsd"> |
121 |
| -
|
122 |
| - <services> |
123 |
| - <service id="App\Form\TaskType"> |
124 |
| - <argument type="service" id="doctrine.orm.entity_manager"/> |
125 |
| - <tag name="form.type"/> |
126 |
| - </service> |
127 |
| - </services> |
128 |
| - </container> |
129 |
| -
|
130 |
| - .. code-block:: php |
131 |
| -
|
132 |
| - // config/services.php |
133 |
| - use App\Form\TaskType; |
134 |
| - use Symfony\Component\DependencyInjection\Reference; |
135 |
| -
|
136 |
| - $container->register(TaskType::class) |
137 |
| - ->addArgument(new Reference('doctrine.orm.entity_manager')) |
138 |
| - ->addTag('form.type') |
139 |
| - ; |
140 |
| -
|
141 |
| -That's it! Your controller - where you create the form - doesn't need to change |
142 |
| -at all: Symfony is smart enough to load the ``TaskType`` from the container. |
143 |
| - |
144 |
| -Read :ref:`form-field-service` for more information. |
| 4 | +The content of this article is no longer relevant because in current Symfony |
| 5 | +versions, form classes are services by default and you can inject services in |
| 6 | +them using the :doc:`service autowiring </service_container/autowiring>` feature. |
| 7 | + |
| 8 | +Read the article about :doc:`creating custom form types </form/create_custom_field_type>` |
| 9 | +to see an example of how to inject the database service into a form type. In the |
| 10 | +same article you can also read about |
| 11 | +:ref:`configuration options for form types <form-type-config-options>`, which is |
| 12 | +another way of passing services to forms. |
0 commit comments