【问题标题】:Define form as service in symfony 3.0在 symfony 3.0 中将表单定义为服务
【发布时间】:2025-11-24 15:00:01
【问题描述】:

我知道还有 2 个关于它的其他问题,但我认为它们都不能解决我要问的问题。

在 Symfony 2.8 中,有一个弃用说明,关于使用“别名”来标记定义为服务的表单,可以使用它传递给“createForm”来获取表单。

所以如果我错了请纠正我,现在我们必须定义没有别名标签的服务:

#src/MyBundle/Resources/config/services.yml
my.form.as.service:
    class: MyBundle\Form\Type\MyFormType
    arguments: ["@doctrine.orm.entity_manager",%myparameter1%]
    tags: { - name: form.type }

在控制器中:

$form = $this->createForm('my.form.as.service');

但这给了我一个表单命名错误,因为表单在 getName 函数中返回“my_name”,并且它希望表单接收 FQCN。好的,在控制器中的其他响应之后我更改为:

use MyBundle\Form\Type\MyFormType;
...
$form = $this->createForm(MyFormType::class)

这行得通,并且在 github symfony 成员中说表单组件完成了所有工作......但是如果我想定义一个具有相同类但使用另一个参数而不是 %parameter1% 的第二个服务怎么办。在 2.8 和更早版本中,我能够定义另一个服务并将其名称传递给 createForm 函数,但现在它直接获取类,我可以这样做吗? (我知道这样做可能很奇怪或不必要或......)。

对于 symfony 成员:我同意 Javiereguiluz 的意见,这种变化会让您编写更多代码,并且让您无法完全控制表单组件如何使用您的服务。是否有必要删除表单别名以使我们的生活如此复杂?谢谢!

【问题讨论】:

    标签: php forms symfony-forms symfony


    【解决方案1】:

    对不起,我一开始看错了你的问题。现在,正确答案

    如果您的表单类型需要动态配置设置(例如参数),则应创建表单类型选项。这允许动态更改此设置:

    class MyFormType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $form, array $options)
        {
            $options['your_setting']; // read the option
        }
    
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setRequired('your_setting'); // add a required option
        }
    }
    

    用法:

    $this->createForm(MyFormType::class, null, [
        'your_setting' => 'some value',
    ]);
    

    或者,您也可以将设置默认为某个静态值或参数:

    class MyFormType extends AbstractType
    {
        private $yourSetting;
    
        public function __construct($yourSetting)
        {
            $this->yourSetting = $yourSetting;
        }
    
        // ...
    
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefault('your_setting', $this->yourSetting);
        }
    }
    

    您可以在OptionsResolver component documentation 中了解更多信息。

    【讨论】:

    • 谢谢Wouter,我说了一个参数来说明什么,但是如果我想要注入不同的服务呢?在 3.0 之前,我能够定义 2 个表单服务,每个服务都需要注入的服务,但是现在……为同一个表单创建 2 个类是唯一的选择吗?如果是的话,我想他们这次更新并没有想太多……
    • @JordiPuig 我可以向你保证一件事,核心团队不会在不权衡所有优点/缺点的情况下做出如此大的改变。您是否有以相同表单类型注入的不同服务的真实用例? (我认为您的表单类型在这种情况下做得太多,您需要其他东西,例如数据转换器/映射器或表单事件侦听器)
    • 现在我没有它,但我很确定它会发生。我在 symfony github 上看到了很多关于这个的讨论,从我的日常工作中我找不到这个改变有什么好处,但是很多人不得不重写很多代码......只是想知道它是否真的改进了系统或这只是为了赚取“几行代码”并避免名称错误。无论如何感谢您的回答。
    【解决方案2】:

    我问了同样的问题并在这里回答了自己:Symfony 2.8/3.0 upgrade: how to deal with form types with variable parameters?

    不幸的是,这是 Symfony 3.0 中的一个限制,并且没有解决方案。

    一种解决方案是为每个表单创建一个类(而不是一个公共的),并让每个表单扩展一个公共抽象类以避免代码重复。

    但这仍然需要您创建许多类,这不是最优的。

    【讨论】:

      最近更新 更多