是否应在Form对象或模型中进行验证?

时间:2009-03-18 20:25:16

标签: php zend-framework validation zend-validate

这个问题主要针对PHP中的Zend,虽然它肯定适用于其他语言和框架,所以我欢迎大家的意见。

我最近才使用Zend框架,虽然它并不完美,但我还是玩得很开心。然而,令我疯狂的一件事是,我看到人们使用Zend的大部分例子都是v alidation in special form objects而不是模型。我认为这是不好的做法,因为数据可以通过除形式输入之外的其他方式进入系统,这意味着必须弯曲和扭曲验证器以验证其他输入,或者必须在第二位进行验证,并且逻辑重复。

我发现其他一些帖子和博客的人与我的方式一样,但是Zend的开发人员出于某种原因做出了这个选择,其他人似乎没有问题地使用它,所以我想在这里得到社区的一些反馈。

正如我所说的,这主要适用于Zend,虽然我认为从整体上看问题很重要,而不是在Zend框架的范围内工作,因为Zend的设计是为了让你可以使用,或者像你希望的那样少。

8 个答案:

答案 0 :(得分:3)

嗯,验证可以在许多不同的级别完成,通常没有一个是“最好的”。当然,模型可以填充不是来自表单的无效数据,但我们也可以创建其数据不会转到任何模型的表单。

此外,模型中的直接验证实际上没有与我们的表单呈现系统集成,如果我们想要显示错误消息并使用用户输入的数据重新填充表单,则会导致问题。

这两种解决方案各有利弊。拥有一个确保我们最终必须在某个级别完成验证的系统是完美的。如果表单不验证某些数据,则模型会执行,反之亦然。不幸的是,我还没有听说过这样的库,但是我必须注意到框架中的验证器不是源独立的。您可以将POST数据传递给它们,但是从正确解析的CSV,MYSQL数据库等中检索的信息也可以完成相同的操作。

答案 1 :(得分:3)

重要的是要记住,与应用程序相关的数据验证并不总是与数据库模式相关的数据验证相同。

考虑一个简单的注册表单,其中用户使用用户名和密码创建帐户。您对密码执行验证,因为您希望密码长度为X个字符,并包含良好的字符类型组合(或其他)。

但这些都与验证数据库插入数据无关,因为您不打算存储纯文本密码 - 您将以某种方式存储它们的哈希值(md5,md5 + salt,随你)。相反,您可以确保您有一个32个字符的十六进制字符串,以便它很可能是正确创建的MD5哈希。

此密码示例不是唯一的方案,只是本主题中的一个很好的解释。

那么答案是什么?我认为没有任何一种解决方案适合所有人。有时你会想要(需要?)两次验证数据。有时你只会在模特中做一次。只需尽可能地满足您的应用需求。

答案 2 :(得分:3)

这是一个非特定的特定答案,但我相信该模型应该对其自身数据的有效性负责。如果是这种情况,那么验证属于模型,但是这可能并不总是可以实现,并且可能需要在视图中执行验证,但是我认为这应该是在模型中执行的验证的补充而不是替换为了它。

仅在视图中进行验证的问题是,在某些时候您可能需要另一个数据视图。您的网站可能会变得流行,客户要求基于XML的API生成自己的视图。您是否依赖客户验证数据?

即使您不必提供API,某些客户也可能希望自定义视图完全不同,以保证页面的版本完全不同,您现在又可以在重复的视图中进行验证。

我认为理想的情况是让您的模型进行验证,但要使视图的验证结果可以再次读取和呈现页面,并显示验证结果。

我认为如果你想立即将验证数据显示给用户等,让视图进行验证是完全合理的,但是关于数据有效性的最终决定应该依赖于模型。

答案 3 :(得分:3)

或许你应该看一下Using Zend_Form in Your Models Matthew Weier O'Phinney - Zend框架的首席开发人员之一 - 以了解他对这个问题的看法。

答案 4 :(得分:0)

我不知道Zend。但

您的模型必须接收有效数据。模型及其方法不应反复检查数据。当然应该有一些功能可以进行实际验证,它们应该从gui验证或其他数据输入位置调用。

您可以在模型方面做的最好的事情是在所有数据上调用“断言”,以确保验证已经取代它的开发时间。

代码的较低级别(UI,model,utils)应该存在较少的验证和检查代码。那时,很有可能同样的验证将被称为多一个。

答案 5 :(得分:0)

如何在表单中进行美学验证,并在模型中进行业务规则验证。

以登记表格为例。

表格将确保电子邮件字段被裁剪并包含有效的电子邮件,密码/确认密码字段相同,并且用户选中了我同意条款复选框。

注册模型将确保表中尚未收到电子邮件,并对密码进行加密和散列。

这就是我通常如何分裂两者。

答案 6 :(得分:0)

用户输入应在输入时进行验证,因为它特定于输入形式(即,进行一些表格验证 - 确保应该有数字的文本框是数字)。

业务逻辑应该在模型上进行验证,因为它是特定于模型的(即确保他们还没有保留相同的房间或类似的东西)。

在模型级别验证它的问题是模型可能以不同的方式使用。一个场景的正确输入可能不是另一个场景的正确输入。

另一个问题是你通常需要一些上下文敏感的验证,例如在表单控件周围显示一个输入错误的红框。

模型或数据库可能会进行一些额外的验证,以确保用户代码没有完全错误(约束等)。

答案 7 :(得分:0)

Peter Bailey的密码示例非常棒。用户模型只能验证,如果设置了密码(因为它没有以纯文本形式存储,而是作为哈希),而输入验证可以确保原始纯文本密码符合安全要求(字符数) ,...)。因此,您需要:模型验证和表单/输入验证,理想情况下是独立的可重用组件,而不是直接在膨胀的控制器操作中。

将输入验证视为白名单验证(“接受已知商品”)并将模型验证视为黑名单验证(“拒绝已知错误”)。白名单验证更安全,而黑名单验证可防止您的模型层过度受限于非常具体的用例。

无效的模型数据应始终导致抛出异常(否则应用程序可以继续运行而不会注意到错误),而来自外部源的无效输入值不是意外的,而是常见的(除非您让用户永远不会犯错误) )。

另请参阅:https://lastzero.net/2015/11/form-validation-vs-model-validation/