I had a quick look at the different ways in which I could get my hands on the form builder in a Symfony 5 controller.
Disclaimer
1) other services are available and 2) this is not an exhaustive list on how to inject and/or access services in a controller.
So, as a starting point, let's assume we've installed Symfony 5.x (either with the Symfony CLI binary or with composer create project) and we have a lovely fresh installation. Let's open up a few files and see what we have... Here's what we'd expect to see in /config/services.yaml
// config/services.yaml services: _defaults: autowire: true // and a bit further down... App\Controller\: resource: '../src/Controller/' tags: ['controller.service_arguments']
Now, if we uncomment the lines in /config/routes.yaml so we have...
// config/routes.yaml index: path: / controller: App\Controller\DefaultController::index
and add a controller...
// src/Controller/DefaultController.php <?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; class DefaultController extends AbstractController { public function index() { $formBuilder = $this->createFormBuilder(); return new Response('Yo!'); } }
Bingo! We can start using the form builder.
Now if you're inheritance-adverse, you might not fancy extending the AbstractController class. Fear not! All we need to do is constructor-inject our dependency using type-hinting as follows:
// src/Controller/DefaultController.php <?php namespace App\Controller; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\HttpFoundation\Response; class DefaultController { protected $formFactory; public function __construct(FormFactoryInterface $formFactory) { $this->formFactory = $formFactory; } public function index() { $formBuilder = $this->formFactory->createBuilder(); return new Response('Yo!'); } }
And this totally works because of the lovely auto-wiring provided by Symfony. Thanks, Symfony!
Lastly, let's take a look at how you'd get access to the form builder if you weren't, for whatever reason, using auto-wiring.
Let's disable auwiring in /config/services.yaml, tag our controller class with controller.service_arguments and bind the form factory service...
// config/services.yaml services: _defaults: autowire: false App\Controller\DefaultController: tags: ['controller.service_arguments'] bind: $formFactory: '@form.factory'
And finally, modify our controller...
// src/Controller/DefaultController.php <?php namespace App\Controller; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\HttpFoundation\Response; class DefaultController { public function index(FormFactoryInterface $formFactory) { $formBuilder = $formFactory->createBuilder(); return new Response('Yo!'); } }
And there we have it, I hope you enjoy playing around with these approaches.