2012-04-18 52 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']; 
} 

您可以使用