用Symfony形式分离关注点

时间:2013-03-14 18:09:22

标签: php oop symfony domain-driven-design modular-design

我最近一直在尝试使用Symfony 2表单,这对于简单表单非常有用。

但是 - 在选择框或类似的东西中使用 - 我经常需要表单中的关联实体列表。在几篇博文和Symfony文档中,他们提出了类似的建议......

//BlogPostType implements FormTypeInterface
public function buildForm(FormBuilderInterface $builder, array $options)
{
  $builder
  ->add('category', null, array(
    'property' => 'name',
    'query_builder' => function(EntityRepository $er) use($options) {
      return $er->createQueryBuilder('category')->orderBy('category.name', 'ASC');
    }
  );
}

由于我非常关注域驱动设计,特别是关注点的分离,我发现很难相信将关联实体绑定到Symfony中的自定义表单类型的唯一选择是查询它在自定义表单类型中。

在我看来,这违反了SoC,因为表格不应该是查询。 这样,表单总是采用相同的实体,但不是应该选择显示哪些实体的形式......

要求表单构建器构建表单的控制器应该将关联的对象注入自定义表单类型构造函数中......或者<... p>

//BlogPostType implements FormTypeInterface
public function __construct(array $categories) {
  $this->categories = $categories;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
  $builder
    ->add('category', null, array(
      'property' => 'name',
      'choices' => $this->categories
    );
}

有谁知道如何实现这一目标?

1 个答案:

答案 0 :(得分:6)

是的,您可以从控制器传递选项。只需创建一个选项而不是通过构造函数注入它,因为只有在为每个请求创建给定类型的第一个表单时才会使用构造函数。因此,如果您碰巧需要在页面上输出多个相同类型的表单,那么如果通过构造函数传递它们,它们的选择将是相同的。

当您注入可以多次重复使用的服务而没有任何问题时,通过构造函数向表单类型注入某些内容是有意义的。

博客和网络上的很多例子都违反了很多最佳实践,但是用一些关于这些实践的例子教新手会更难。