Symfony2:如何在表单类中获取配置参数

3
如果我在控制器中,可以轻松地使用以下代码读取配置参数:
$this->container->getParameter('profession');

但是当我在其他一些类中,比如Form类型时,我怎么获取配置参数呢?

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

上述代码不应该也没有起作用。
8个回答

8
另一个类似的解决方案是将表单类型设置为服务并注入所需的参数。 然后,您的控制器只需要抓取该服务即可。 将参数名称用百分号括起来。
在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>

如果你真的想这样做,你可以注入完整的容器,但是这种做法是不被鼓励的。


5

现在您可以使用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()
                          ]);
        }
}

在services.yml文件中:

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

2
传递容器是一个不好的习惯。你应该只传递所需的参数。 - Strayobject

3

一个简单的解决方案是给你的类型(Type)添加一个新变量,用于存储配置参数的值。你可以将它设为公共变量(不建议),添加一个构造函数参数或使用setter方法:

class MyType extends AbstractType{

    private $profession;

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

    // ...

}

您可以在控制器中像这样使用它:
$myType = new MyType($this->container->getParameter('profession'));
// use mytype with form

毕竟,表单不应该知道容器的存在,因为这样会把它们捆绑在一起,使得测试或交换容器变得困难。这与容器的整个理念背道而驰。
另一方面,使用构造函数/设置器来注入参数相当不错,因为您在测试时不需要知道它们来自哪里,可以随时更改它们的来源,并且像上面说的那样,不依赖于容器。

2
谢谢,这个方法可行。但是我已经将其实现为一个服务并注入了参数。我认为这是更好的方法。 - Amit

1
在Symfony 4中,您应该首先将表单定义为服务,然后在config/services.yaml中传递正确的参数。
parameters:
    locale: 'en'
    upload_dir: '%kernel.project_dir%/public/uploads/avatars'

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

在你的表单类中获取参数(这里是上传目录)的方法如下:

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

我希望它有所帮助


1
在Symfony 4.1中,您只需要将ParameterBagInterface添加到表单构造函数中即可:
public function __construct(ParameterBagInterface $parameterBag)
{
    $this->parameterBag = $parameterBag;
}

然后获取您的参数:
$profession = $this->parameterBag->get('profession');

0

你也可以使用Setter Injection。从http://symfony.com/doc/current/book/service_container.html#optional-dependencies-setter-injection

如果你的类有可选依赖项,那么“setter injection”可能是更好的选择。这意味着使用方法调用而不是通过构造函数注入依赖项。该类将如下所示:

namespace AppBundle\Newsletter;

use AppBundle\Mailer;

class NewsletterManager
{
    protected $mailer;

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

    // ...
}

通过setter方法注入依赖项只需要更改语法:

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

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

当 setter 被调用时? - Miguel Carvajal
它由Symfony服务容器自动调用。 - Aris
这解释了谁通过我的问题调用它,以及在对象生命周期的哪个时刻调用它。当我使用服务时,我有没有保证 $mailer 不会为空? - Miguel Carvajal

0

在Symfony3中,可以这样做 -

在控制器中

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

在 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'];
}

您可以在表单中使用上述值


-1

在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');
        // ...
    }
}

请参考此链接:https://symfony.com/blog/new-in-symfony-4-1-getting-container-parameters-as-a-service

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接