模型/视图/控制器模型中validation的最佳位置?
我正在开发一个广泛使用MVCdevise模式的PHP项目。 我正在寻找添加validation到一个表单,并好奇什么是正确的地方进行validation。
由于生成表单的方式,对回发数据的validation在视图组件中更简单,重复性更低。 让视图validation响应数据是可以接受的,还是应该在控制器甚至模型中实现?
有什么好处?
如果你正在validation客户端的数据(即Javascriptvalidation),这是绝对不够的,不安全的,你应该在视图中实现它。
如果您在服务器端validation数据,并且您的validation不需要应用程序业务逻辑(即,您不检查用户是否有足够的信用在他的帐户),您应该在控制器中validation。
如果validation需要业务逻辑,则在模型内实现并通过控制器调用它。
回传validation不好,因为它会带来很大的压力和延迟,唯一的好处是程序员(不会被记账)。
您可以使用正则expression式进行大多数validation,在PHP和JS上具有相同的语法(几乎)。
validation的正确位置是模型 。
这是最有意义的,因为您正在对数据进行validation,这是模型所代表的。 在CRUD更新方面,应该总是以某种方式使用模型。
-
如果您要更改视图中的数据,则应该检查validation。
-
如果你有控制器改变数据,你应该检查validation。
-
最后如果你有模型本身改变数据,你应该仍然有validation。
实现这种状态的唯一方法是validation进入模型。
由于性能和响应速度较快,在模型中实现validation之后,应该尝试添加某种客户端(JS)来立即通知最终用户。
validation始终是关于数据的。 你为什么要validation数据? 所以你可以保持你存储信息的完整性。 在模型层面进行validation可以使数据在理论上永远是正确的。 这永远是一个必要条件。 从那里你可以添加额外的validation在您的业务逻辑和客户端,使您的应用程序更加用户友好。
在模型中的validation似乎是最常见的方法(你最终得到像$obj->isValid()
),这在许多情况下是合适的。
但是,根据您的使用情况,可能有充分的理由在模型之外执行validation,使用单独的validation代码或在控制器中:
- 如果大部分validation问题涉及到模型无法访问的信息(例如,如果pipe理员用户可以执行常规用户无法执行的转换,或某些date后某些属性不能更改),则可能需要检查所有这些约束在同一个地方。
- 构buildtesting对象时,应用非常宽松的validation规则也可能是方便或必要的。 (一个“购物篮”对象通常可能需要一个关联的用户,而这个用户又需要一个有效的电子邮件地址等等。一个100%有效的购物篮对象可能不方便在购物篮unit testing中构build。
- 由于历史原因,validation规则可能会发生变化(例如,在以前没有必要的情况下执行“性别”),因此您可能会得到不同版本的数据,需要区别对待。 (不同的validation规则也可能适用于批量数据导入。)
- 如果validation非常复杂,则可能需要提供不同的错误消息(或者根本不提供),具体取决于调用者最有用的内容。 在其他情况下,
true
或false
可能是所有必要的。
通过模型的isValid()
方法的参数来处理这些不同的用例也是可能的,但是随着validation样式数量的增加,这变得越来越难以应用。 (我认为几乎可以保证一个单一的“一刀切”的isValid()
方法最终将certificate不足以满足大多数不平凡的项目。)
不要混淆与validation消毒或清洁张贴值。 您应该获取发布的值,并通过从Controller中的值中删除任何恶意元素来清理它们。 然后将数据发送到模型以validation期望值或格式。 通过将这些操作分为两个过程,可以降低恶意代码执行的风险。 如果您使用“信任无人投入”政策,此方法运作良好; 知道一些程序员可能变得马虎或懒惰。 另一个积极的方面是防止你的模型变得臃肿和过度工作,如果是的话,然后使用模型助手做肮脏的工作。 这种方法还将有助于平衡应用程序负载并提高性能。