我越多地使用 Symfony2 并与它的形式作斗争,我就越得出结论,它们是一个巨大的可怕的野兽,甚至不应该真正存在。
我看到了这篇文章 here我发现我同意作者的观点。即使这篇文章是针对 Symfony 1.x 的,我认为它仍然适用于 Symfony2 中的 Form 组件。看起来表单组件确实试图在一个地方解决属于模板、 Controller 和模型的问题。这不会严重违反 MVC 和/或 SRP(单一职责原则)吗?
这可能是一个不同的问题,但我觉得它有点相关 - 我还注意到 symfony 的许多可用包都试图解决 View 之外的 View 问题,例如:
KnpMenuBundle - 您在服务器端使用 oo 接口(interface)生成菜单(为什么不在它们所属的 View 层中?)
IvoryCKEditorBundle - 将 textarea 转换为 ckeditor 是在 View 文件中的一行 jquery 中完成的,那么为什么存在这个包?我什至不想数那里的行数。
所以在 Symfony 的核心中似乎到处都存在这些违规行为,还是我只是不明白?
最佳答案
关于表单处理的问题是它违反了 MVC 的定义。这是一个被称为“横切”的问题,过去已经被科学研究过。论文Domain Driven Web Development With WebJinn ,例如,是关于该主题的有趣读物。
例如,考虑表单与 MVC 不同层的关系:
型号:
- 表单复制域模型 (DM) 的信息结构。如果您更改此结构(例如,通过向数据结构添加字段或向过程添加参数),您还必须调整表格以输入该信息。
- 他们需要来自您的 DM 的类型信息,以将输入转换为那里所需的类型。
- 他们需要知道您的 DM 中指定的约束以验证输入。
- 理想情况下,他们直接从您的 DM 读取数据和向您的 DM 写入数据(例如,通过读取/写入数据结构的字段或通过使用提交的值作为参数调用 DM 中的过程)。
Controller :
- 表单接收提交的数据并将其发送到 DM。
- 他们根据验证是否成功来改变程序流程。
查看:
- 表单呈现为 HTML 标记和属性的复杂结构,它取决于以上所有内容(是否需要一个字段?是否应该显示错误?如何对字段进行排序?在下拉列表中提供哪些选择?等.)
因此,不可能编写一个不涉及所有这些层的表单抽象机制。相反,解决方案是根据 MVC 将表单库本身构建为不同的层和子组件,以实现 SRP。如果您查看 Symfony2 Form 组件,它会做得很好。 ;)
那么为什么它会是这样一头“巨大的可怕野兽”呢?第一个问题是抽象。以一个简单的下拉列表为例。如果我们想重用下拉菜单的代码,我们需要以某种方式对其进行抽象。现在检查上面的列表,即使是这个简单的输入也会触及 MVC 应用程序的所有三个层。您如何将原本应该构造成三个不同部分的东西抽象出来?
第二个问题是特征多样性。表单库永远无法解决开发人员在日常生活中面临的所有问题。因此,所有这些层和抽象机制都需要可扩展,以便您可以使它们的行为完全符合您的要求。
虽然可扩展,但 Form 组件已经解决了数百个您甚至不必再考虑的小问题。如何输入日期,如何使用不同的 UI(下拉菜单、复选框、单选按钮等)选择一个或多个选项列表,如何再次保护表单安全漏洞等等,这些都是我可以写论文的主题关于。
您会发现表单库非常复杂。我们在编写此类“巨大的可怕野兽”时最好的选择是使它们的 API 对于初学者尽可能简单,对于更高级的用户尽可能灵活,并编写大量文档以充分利用其全部功能。最后一点肯定仍然缺乏 ( please help! ),但我们正在不断努力解决上述所有问题。
另一方面,不幸的是,将复杂问题简化为简单问题是不可能的。
其他更简单的表单库呢?以我的拙见,这些甚至没有尝试解决 Symfony2 Form 组件已经为您解决的大部分问题。 :)
2014 年 1 月 24 日更新: 对于任何想了解更多(更多)的人,这里是 a paper that I published on the subject .
关于php - Symfony2 表单组件 - 违反 MVC 和 SRP?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15761785/