|
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