MVC问题:我应该在控制器或模型中放置表单验证规则吗?

Cli*_*ote 50 php codeigniter

一方面,表单验证可以被视为应用程序逻辑的一部分,因此属于模型.

另一方面,它直接处理来自视图的输入并处理显示错误等.从这个角度来看,将它放入控制器更有意义.

从MVC的角度来看哪一个是正确的方法?

PS我的表单验证实际上只包括编写字段列表,它们的规则,并将其传递给表单验证库,它返回true/false是否通过验证.

例:

$this->load->library('form_validation');
$this->form_validation->set_rules('name', 'Name', 'required');
$this->form_validation->set_rules('email', 'Email', 'required|valid_email');
//........
if ($this->form_validation->validate())
    // Process data
else
    $this->register_form(); //A controller action that will show a view with errors
Run Code Online (Sandbox Code Playgroud)

这应该放在控制器或模型中吗?

Wes*_*rch 72

理想情况下,您需要3层验证:

  1. 查看:客户端(javascript,html5验证等).这会在数据到达控制器之前捕获明显的错误和遗漏,浪费用户的时间并在出现错误时调用不必要的页面加载.
  2. 控制器:这是您的表单验证层.控制器通常用于直接处理输入,并将其发送到模型.表单中的每个字段都非常罕见,您的数据库中有一个直接相关的列,您通常需要在将数据传递给模型之前以某种方式更改数据.仅仅因为您需要验证一个名为"确认电子邮件"的字段,并不意味着您的模型将处理"确认电子邮件"值.有时,这将是最后的验证步骤.
  3. 模型:这是验证的最后一道防线,可能是您在向模型发送数据时的唯一验证,不是直接来自表单帖子.有很多时候需要从控制器调用向数据库发送数据,或者使用非用户输入的数据.我们不希望看到数据库错误,我们希望看到应用程序本身抛出的错误.模型通常不应直接处理$ _POST数据或用户输入,它们应该从控制器接收数据.您不希望像电子邮件确认那样处理无用的数据.

  • 而已!控制器只是一个验证层!但Controller不包含验证规则,也不知道如何验证用户提供的数据!控制器只知道请求了哪个动作,动作创建了一个知道如何验证数据的体面模型.如果数据验证(BY MODEL)失败,则控制器只会呈现具有错误的适当视图.这正是我所说的.因此,数据验证完全是模型问题.我想每个人都会混淆验证层(此时应该验证数据)和验证位置(由谁/哪里应该验证数据). (11认同)

Nem*_*den 19

验证是Model的问题.只有模型知道您的数据应该是什么样子.您在模型中描述了数据字段,因此您应该在同一位置描述此字段的验证规则.

对我来说这似乎很明显,但我很乐意听取对手的意见.

  • 他应该在模型中设置数据库验证(假设它是一个db模型)和控制器中的http数据验证.例如,Xss过滤与模型无关.它与输入中的Controller和输出中的View有关. (18认同)
  • 我们这里不讨论数据过滤,而是验证.为什么你不能在模型中执行过滤?您已从Web表单加载数据,将其加载到模型中,模型验证数据,对其进行过滤,并将其保存到您想要的任何位置.过滤XSS只是数据转换,数据属于Model.也许我需要一些例子?...模型不是关于他们保存数据的地方.如果您的模型在数据库或文件中存储数据或者不在任何地方保存数据,那么无关紧要,只需通过电子邮件发送此数据(电子邮件发送表单)...... (2认同)
  • @Madmartigan问题是,你认为模型只与数据库中的内容有关.事实并非如此,该模型的工作是处理包括信用卡处理和验证在内的所有业务逻辑.您应该有一个预订模型,用于验证表格并存储预订,以及订单模型,用于处理/验证cc.控制器首先通过预订模式验证表格,然后通过订单模型验证+费用cc,然后通过预订模型存储订单.如果有任何错误,它会将它们传递给查看. (2认同)

小智 12

我想说在大多数情况下,表单验证代码应该在控制器(而不是模型)中.

Madmartigan在上面的评论中说得最好"表单验证!==数据验证.并非所有表单都与模型交互"

Web表单在逻辑上是MVC的View/Controller部分的一部分,因为用户在视图中与它们交互.

  • 什么样的形式不与模特互动?在我看来,您可以为所有类型的表单创建模型.数据DOES属于Model.维基:"该模型不一定仅仅是一个数据库;**MVC中的'模型'是数据和业务/域逻辑需要在应用程序中操纵数据**".在Controller中验证数据会使您的模型不完整.模型包含知道如何处理数据的业务逻辑.如果您在处理之前未验证数据(您忘记在Controller中执行此操作),那么您将遇到麻烦.在我的情况下,我永远不会忘记验证我的数据 (5认同)
  • @JohnWright在CodeIgniter中,'form_validation'是一个'库',它同样可供控制器和模型使用.此外,将它放在模型中实际上更有意义,因为如果你有两个具有相同字段的表单:注册和'我的帐户',但是使用不同的控制器,两个控制器都可以调用$ this-> user_model-> validate ()查看表单是否已经过验证. (4认同)
  • 我同意Nemoden,它是模型的责任,而不是控制器.我想你应该多读一些关于MVC的内容. (3认同)
  • +1 - 我同意。在我看来,如果它是数据属于模型的想法在这里不适用。 (2认同)

Rya*_*ams 5

似乎每个人总是说模型提到这个问题,这有其优点(与相反的情况相比),但我认为这个问题的答案更为微妙.应该在模型上执行数据本身的验证.

但是还有其他类型的验证,例如表单是否已经提交了意外字段(显然是出于安全目的),或者用户是否有权请求操作.通过在模型中放置这些类型的验证,它可以粘合模型(数据的抽象)以完全分离事物,例如用户系统如何工作或如何为安全目的评估表单提交.

您可以想象更改其中一个类或类系统,然后弄乱,因为您还必须更改所有模型.而控制器是客户端输入和数据之间的中介:在该角色中,它们是上述示例的适当验证器,可能还有许多其他验证器.