如果我在控制器内,我可以使用以下方法轻松读取配置参数:
$this->container->getParameter('profession');
但是当我在其他班级时,比如 Form 类型,我怎样才能掌握配置参数?
$container = new Container();
$container->getParameter('profession');
上面的代码不应该也不起作用。
如果我在控制器内,我可以使用以下方法轻松读取配置参数:
$this->container->getParameter('profession');
但是当我在其他班级时,比如 Form 类型,我怎样才能掌握配置参数?
$container = new Container();
$container->getParameter('profession');
上面的代码不应该也不起作用。
另一个类似的解决方案是让您的表单类型成为服务并注入所需的参数。然后你的控制器需要做的就是获取服务。用百分号将参数名称括起来。
在 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>
如果您真的想要,那么您可以注入完整的容器,尽管不鼓励这样做。
现在您可以使用 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' }
一个简单的解决方案是为您的 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
毕竟,表单根本不应该知道容器,因为您会将它们捆绑在一起,从而难以测试或更换容器。这将违背容器的整个想法。
另一方面,使用构造函数/设置器来注入参数是相当不错的,因为您在测试时不需要知道它们来自哪里,可以随时更改它们的源,并且如前所述,没有依赖关系到容器。
在 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;
}
}
我希望它有帮助
在 Symfony 4.1 中,您只需要ParameterBagInterface
在 Form 构造函数中添加:
public function __construct(ParameterBagInterface $parameterBag)
{
$this->parameterBag = $parameterBag;
}
然后获取您的参数:
$profession = $this->parameterBag->get('profession');
您还可以使用 Setter 注入。来自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']]
在 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'];
}
您可以在表格中使用上述值
在 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