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

问题描述 投票:3回答:7

如果我在控制器内,我可以使用以下方法轻松读取配置参数:

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

但是当我在其他课程中,说一个Form类型时,我怎样才能获得配置参数?

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

上面的代码不应该也不起作用。

symfony symfony-forms
7个回答
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' }

3
投票

一个简单的解决方案是为您的Type提供一个新变量,用于存储config参数的值。您可以将其公开(不推荐),添加构造函数参数或使用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

毕竟,表格根本不应该知道容器,因为你将它们系在一起,这使得很难测试或更换容器。这将违背容器的整个想法。

另一方面,使用构造函数/ setter来注入参数是相当不错的,因为您不需要知道它们在测试时的来源,可以随时更改其源,并且如上所述,没有依赖性到容器。


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;
    }
}

我希望它有所帮助


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']]

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

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


0
投票

在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

© www.soinside.com 2019 - 2024. All rights reserved.