简体   繁体   中英

Symfony: how to get a parameter from the route within a FormType?

I'm trying to access the parameter page from the current route within a FormType . It works in a Controller , but not in a FormType . I'd like to avoid passing the parameter like /?page=1 and prefer /page/1 .

routing.yml

my_route:
    path: /data/page/{page}
    defaults:
        _controller: MyBundle:MyController:myAction

src/myBundle/Form/Type/MyFormType.php

class MyFormType extends AbstractType {
    // ...
    public function buildForm(FormBuilderInterface $builder, array $options) {
        $request = Request::createFromGlobals();
        $page    = $request->query->get('page');
        echo "page: $page"; // empty

        // ...
    }
}

I'd like to avoid to pass the parameter through the Controller to the FormType and prefer to access it directly within the FormType.

Any ideas?

Thanks in advance!

Edit: Regarding the selected answer; the page attribute is accessible via $request->attributes->get('page') , not via $request->query->get('page') .

I'm not sure the answer provided by Yonel is the best because you inject a dependency to your form. It has some drawbacks and the major one IMHO is that it will make the test difficult as the dependency on the page parameter is hidden.

A better solution will be to add it as form option to your form.

The request object is already available in your controller and you are probably creating your form this way :

$form = $this->createForm(WhateverFormType::class, $entity)

Using the createForm method, you can inject a third argument which are the options (ie additional data) you want to pass to your form.

So in your controller :

$page = $request->query->get('page');
$form = $this->createForm(WhateverFormType::class, $entity, ['page' => $page]);

And in your form type, follow the example given in this answer for the same question : https://stackoverflow.com/a/10922788/2721918

You need to inject the request stack service into form type to do that:

class MyFormType extends AbstractType 
{
    private $requestStack;

    public function __construct(RequestStack $requestStack)
    {
        $this->requestStack = $requestStack;
    } 

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $request = $this->requestStack->getCurrentRequest();

        //do something: for example hide/show fields from request parameters  
    }
}

Register the form type and their dependencies:

services:
    app.form.type.myform:
        class: AppBundle\Form\Type\MyFormType
        arguments: ['@request_stack']
        tags:
           - { name: form.type }

However, is recommended instead to create the new option to pass all variables that you need for your form type.

It is not necessary to inject the request stack service in the construct of your formtype. You can access to the requestStack by using form event listener like that:

$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$form = $event->getForm();
$form->getConfig()->getRequestHandler();
// do what you need...
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM