2012-04-18 51 views
2

如果我是一个控制器内,我可以很容易地读取配置参数,以获得配置参数表类:的Symfony2:如何使用

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

但是,当我在其他一些类,比如表单类型,我怎样才能获得配置参数?

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

上面的代码不应该也不行。

回答

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> 

如果你真的想那么尽管这是鼓励你可以注入完整的容器。

3

一个简单的解决方案是给你的类型一个新的变量,你存储你的配置参数的值。您可以把它公开(不推荐),添加一个构造函数的参数,或者使用一个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 2012-04-19 07:32:35

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方法的依赖只需要语法的变化:在服务

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() 
          ]); 
     } 
} 

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

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

当调取者被调用? – 2017-01-04 20:55:15

+0

它由Symfony服务容器 – Aris 2017-01-06 06:55:49

+0

自动调用,这解释了由我的问题调用它的人是在它调用的对象生命周期的哪个点。我有任何保证,当我使用该服务时,$ mailer不会为空? – 2017-01-07 11:47:33

5

现在你可以使用ContainerAwareInterface 。阳明:

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

通过容器周围是一个坏习惯。您只应通过必需的参数。 – StrayObject 2017-01-06 18:18:54

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

您可以使用