Symfony2: how to get config parameters in Form classes

╄→尐↘猪︶ㄣ 提交于 2019-12-10 17:48:44

问题


If I am inside a controller, I can easily read the config parameters using:

$this->container->getParameter('profession');

But when I am in some other class, say a Form type, how can I get hold of the config parameters?

$container = new Container(); 
$container->getParameter('profession');

The above code shouldn't and doesn't work.


回答1:


Another similar solution is make your form type a service and inject the needed parameters. Then all your controller needs to do is to grab the service. Surround the parameter name with percent signs.

In services.xml

    <service
        id     = "zayso_area.account.create.formtype"
        class  = "Zayso\AreaBundle\Component\FormType\Account\AccountCreateFormType"
        public = "true">
        <argument type="service" id="doctrine.orm.accounts_entity_manager" />
        <argument type="string">%zayso_core.user.new%</argument>
    </service>

And if you really wanted to then you could inject the complete container though that is discouraged.




回答2:


Now you can use ContainerAwareInterface:

class ContactType extends AbstractType implements ContainerAwareInterface
{
        use ContainerAwareTrait;

        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder->add('choice_field', ChoiceType::class, [
                            'choices' => $this->container->get('yourservice')->getChoices()
                          ]);
        }
}

in services.yml:

app.contact_type:
    class: AppBundle\Form\ContactType
    calls:
      - [setContainer, ['@service_container']]
    tags:
        - { name: form.type, alias: 'container_aware' }



回答3:


One easy solution is to give your Type a new variable where you store the value of your config parameter. You can either make it public (not recommended), add a constructor parameter or use a setter:

class MyType extends AbstractType{

    private $profession;

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

    // ...

}

You would use this in your controller like this:

$myType = new MyType($this->container->getParameter('profession'));
// use mytype with form

After all, the form should not know about the container at all as you would tie them together making it hard to test or exchange the container. This would be against the whole idea of the container.

On the other hand, using a constructor/setter to inject parameters is rather nice, as you don't need to know where they come from when testing, can change their source anytime you want and, as said, don't have a dependency to the container.




回答4:


in Symfony 4 you should first define your form as a Service then in config/services.yaml pass your proper parameter to it

parameters:
    locale: 'en'
    upload_dir: '%kernel.project_dir%/public/uploads/avatars'

services:
    App\Form\FilemanagerType:
        arguments: ['%upload_dir%']
        tags: [form.type]

and inside your form class get parameter (here upload dir) like this

class FilemanagerType extends AbstractType
{
    private $upload_dir;
    function __construct(string $upload_dir)
    {
        $this->upload_dir= $upload_dir;
    }
}

I hope it helps




回答5:


You can also use a Setter Injection. From http://symfony.com/doc/current/book/service_container.html#optional-dependencies-setter-injection :

If you have optional dependencies for a class, then "setter injection" may be a better option. This means injecting the dependency using a method call rather than through the constructor. The class would look like this:

namespace AppBundle\Newsletter;

use AppBundle\Mailer;

class NewsletterManager
{
    protected $mailer;

    public function setMailer(Mailer $mailer)
    {
        $this->mailer = $mailer;
    }

    // ...
}

Injecting the dependency by the setter method just needs a change of syntax:

# app/config/services.yml
services:
    app.mailer:
        # ...

    app.newsletter_manager:
        class:     AppBundle\Newsletter\NewsletterManager
        calls:
            - [setMailer, ['@app.mailer']]



回答6:


In Symfony3, It can be done like this -

At Controller

$form = $this->createForm(FormType::class, $abc, array('firstargument' => $firstargumentvalue, 'second' => $secondvalue));

At FormType

public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array('data_class' => abc::class, 'firstargument' => null, 'second' => null));
    }

public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $first = $options['firstargument'];
        $second = $options['second'];
}

You can use the above values in the form




回答7:


In Symfony 4.1

services:
    # ...
    _defaults:
        bind:
            $projectDir: '%kernel.project_dir%'
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;

class MessageGenerator
{
    private $params;

    public function __construct(ParameterBagInterface $params)
    {
        $this->params = $params;
    }

    public function someMethod()
    {
        $parameterValue = $this->params->get('parameter_name');
        // ...
    }
}

Please refer this https://symfony.com/blog/new-in-symfony-4-1-getting-container-parameters-as-a-service



来源:https://stackoverflow.com/questions/10204219/symfony2-how-to-get-config-parameters-in-form-classes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!