【发布时间】:2011-10-12 11:30:00
【问题描述】:
我已经四处搜索,但似乎没有一个关于哪个更好的明确共识。目前,站点上的所有 HTML 表单都指向一个 PHP 文件。每个表单都有一个隐藏的输入指定操作(例如“用户登录”、“用户注销”),PHP 文件从中调用方法。
所以我的问题是:我应该将每个表单指向自身,将相关表单指向单个文件还是 所有 表单指向单个文件?而在MVC方面,处理应该发生在控制器还是表单中?
【问题讨论】:
我已经四处搜索,但似乎没有一个关于哪个更好的明确共识。目前,站点上的所有 HTML 表单都指向一个 PHP 文件。每个表单都有一个隐藏的输入指定操作(例如“用户登录”、“用户注销”),PHP 文件从中调用方法。
所以我的问题是:我应该将每个表单指向自身,将相关表单指向单个文件还是 所有 表单指向单个文件?而在MVC方面,处理应该发生在控制器还是表单中?
【问题讨论】:
我应该将每个表单指向自身,相关表单指向单个文件还是所有表单指向单个文件?
您应该将所有内容指向index.php,然后它会委托其他组件(MVC 术语中的控制器)来处理处理。 controller 将决定它想要渲染哪个 view。 index.php 在这种情况下是我们称之为前端控制器的东西。 (注意:下面我推荐ZF1作为学习平台。ZF1有一个“前端控制器”类。有人可能会说那个是前端控制器,index.php就是他们所说的入口脚本。在我看来,这只是第二个“前端”控制器。尽管如此,两种观点都有争议,所以请提出自己的观点)。
而就 MVC 而言,处理应该发生在控制器还是表单中?
首先就 OOP 而言:对象是唯一知道如何验证其自身数据的对象(自包含原则),因此表单应自行验证。如果是关于模型,则模型应该由控制器或表单调用 - 这是一个品味问题。无论哪种方式,都适用相同的原则:您向模型提供数据并调用 其 验证方法。
您可能已经注意到,Form 类是 Model。
不要让自己被称为 MVC 的炒作所迷惑。 首先尊重 OOP 原则。
关于 MVC:MVC 模式说:控制器只协调其他组件,例如它接受输入,创建 Form 实例,并调用 Form 的验证方法。
我建议您使用一个框架来更好地了解所有这些部分是如何协同工作的。最好的是 zend 框架 1,它与现实生活需求无关,但在模式和实践方面是杰作。
也许 ZF2 会用额外的前置控制器来改变这个错误。
查看其他答案,我觉得有必要澄清我的答案中使用的一些术语:
Model 是模特。有很多关于 MVC 的文档Form 是 Model 的子类。它负责验证。它也可能有一个方法 Form::__toString() 在 view(MVC 中的 V)中呈现 HTML 表单回顾一下,整个执行流程如下所示:
<form action ...Controller协调所有动作,调用一个或多个模型的Model::validate()(包括Form,也是Model)Controller 选择了 render() 一个视图(一个 html 文件),其中可能包含对 Form::__toString() 的调用,在这种情况下,Form 是 Model 和“渲染器”。基本上就是这样。不同的框架有不同的数据/执行流程。例如 ZF1 的外观是这样的:http://www.slideshare.net/polleywong/zend-framework-dispatch-workflow
【讨论】:
在 MVC 术语中,您的处理应该在控制器中进行。您的表单(视图)中不应该有任何处理逻辑。是否为每个表单设置不同的控制器取决于您。例如,您可以有一个控制器来接受所有表单提交并执行一些常见的处理(例如 csrf 检测),然后为每个表单调用其他控制器。或者,您可以有一个控制器来从数据库加载验证要求,并根据提交的表单表现出不同的行为。
【讨论】:
在 MVC 术语中,将所有表单指向一个脚本意味着您有一个 表单前端控制器。有一个控制器处理表单请求。
我应该将每个表单指向自身,相关表单指向单个文件还是所有表单指向单个文件?
这取决于您的需求,设计甚至可能是您网站的架构。
而就 MVC 而言,处理应该发生在控制器还是表单中?
MVC 中的处理通常发生在控制器(仅轻度)和模型(繁重的处理)中。因此,如果您正在寻找一个示例性的 MVC 设计实现,您很可能会拥有 Controller(s) 使用的 Form Models。
这将确保您可以更灵活地使用表单,并且您不会在应用程序中重复用于表单处理的代码。
【讨论】:
在我看来,您应该为每个目的使用一个文件。与 mvc 结构相同,这是一种很好的编程方法,当您的代码变得非常复杂时,它会很有帮助。
【讨论】:
您的问题与Front Controller Pattern 密切相关。在我看来,将非常东西指向某个脚本不会有任何损失,但可以灵活地执行某些操作,而不必重复(并且可能在某个地方忘记)这些操作。
所以我建议将所有表单都指向一个脚本。
顺便说一句。它是根据 Web MVC 处理表单的控制器。
【讨论】:
根据我对 Flavius 回答的评论......
封装表单的对象应该用于向用户呈现表单和检索从用户返回的数据。使用 2 个不同的代码集对同一数据集进行操作会破坏封装原则。考虑您的登录表单是否有名称和密码字段。如果您决定要处理密码的 sha1 哈希来代替原始值,您可能需要在 2 个不同的地方修改 2 位代码!
这并不意味着表单对象的两个实例都需要在同一个 URL 路径中实现;考虑 PHP 的 'require' 和 auto_include 结构。
多个输入集通过相同的 URL 路径多路复用,这称为前端控制器模式。
与更分散的方法相比,前端控制器存在优点和问题。
前端控制器:
非前端控制器:
【讨论】: