If you use the Symfony 2 form builder and create your form types as classes then you may already know that you can define those form types as services and call them in your controller. That process is well documented in the The Book, and works very well. I have an alternative solution which is to define the form itself as a service, which allows you to easily use that form in other model or service classes outside of the controller. This is useful if you have a separate class that handles form submission which may need the form as well and you can inject the actual form into that service.
The typical way of defining a form type as a service and using the form factory to create the form in the controller looks like this:
# src/Acme/TaskBundle/Resources/config/services.yml services: acme_demo.form.type.task: class: Acme\TaskBundle\Form\Type\TaskType tags: - { name: form.type, alias: task }
// src/Acme/TaskBundle/Controller/DefaultController.php // ... public function newAction() { $task = ...; $form = $this->createForm( 'task', $task ); // ... }
To use the Symfony 2 form factory to create the form in the service container, add the following to your services config file.
If you use YAML:
# src/Acme/TaskBundle/Resources/config/services.yml services acme_demo.form.task: factory_method: createNamed factory_service: form.factory class: Symfony\Component\Form\Form arguments: - task_form # name of the form - task # alias of the form type - null # data to bind, this is where your entity could go if you have that defined as a service - { validation_groups: [Default] } # validation groups acme_demo.form.type.task: class: Acme\TaskBundle\Form\Type\TaskType tags: - { name: form.type, alias: task }
If you use XML:
<!-- src/Acme/TaskBundle/Resources/config/services.xml --> <services> <service id="acme_demo.form.task" factory-method="createNamed" factory-service="form.factory" class="Symfony\Component\Form\Form"> <argument>task_form</argument> <!-- name of the form --> <argument>task</argument> <!-- alias of the form type --> <argument>null</argument> <!-- data to bind, this is where your entity could go if you have that defined as a service --> <argument type="collection"> <!-- validation groups --> <argument key="validation_groups">Default</argument> </argument> </service> <service id="acme_demo.form.type.task" class="Acme\TaskBundle\Form\Type\TaskType"> <tag name="form.type" alias="task" /> </service> </services>
Now you can call your form like this in your controller
// src/Acme/TaskBundle/Controller/DefaultController.php // ... public function newAction() { $task = ...; $form = $this->get( 'acme_demo.form.task' ); // set initial form data if needed $form->setData( $task ); }
Wherever you have the service container you can call the form and you can inject the form into other services, as you may want to do with a class that handles form submission.
beware! with this approach DI will always returns the same Form
that differs from
Controller::createForm
doesn’t have to, if you define the proper scope
Very good.
I was trying to do so. For I use in ZF2 this way. But I was kind of lost in yaml.
Thanks and good job.
Go to https://github.com/symfony/symfony/issues/17013 aliemre’s comment for Symfony 3
if i am using a symfony 3.2 version then how can i register form….?