php 模型/视图/控制器模型中验证的最佳位置?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5305854/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best Place for Validation in Model/View/Controller Model?
提问by Lea Hayes
I am working on a PHP project which makes extensive use of the MVC design pattern. I am looking to add validation to a form and am curious as to what the right place for validation is.
我正在开发一个广泛使用 MVC 设计模式的 PHP 项目。我希望向表单添加验证,并且很好奇验证的正确位置是什么。
Due to the way that forms are generated, validation on postback data is a lot simpler and less repetitive in view components. Is it acceptable to have the view validating response data, or should this be implemented within the controller, or even the model?
由于表单的生成方式,对回发数据的验证在视图组件中要简单得多,重复性也少得多。让视图验证响应数据是否可以接受,还是应该在控制器甚至模型中实现?
What are the benefits?
有什么好处?
采纳答案by AbiusX
If you're validating the data on client side (i.e Javascript validation) which is absolutely not enough and not secure at all, You should implement it in View.
如果您在客户端验证数据(即 Javascript 验证),这绝对不够并且根本不安全,您应该在 View 中实现它。
If you're validating data on server side, And your validation does not require application business logic (i.e you're not checking to see if the user has enough credit in his account), You should validate in the controller.
如果您在服务器端验证数据,并且您的验证不需要应用程序业务逻辑(即您不检查用户帐户中是否有足够的信用),您应该在控制器中进行验证。
If the validation requires business logic, Implement it inside the model and call it via controller.
如果验证需要业务逻辑,在模型内部实现它并通过控制器调用它。
Postback validation is not good since it puts lots of pressure and delay, And the only advantage is to the programmer (not to be accounted).
回发验证不好,因为它带来了很多压力和延迟,唯一的好处是对程序员(不考虑)。
You can use regex for most of validation, Which has the same syntax (almost) on PHP and JS.
您可以使用正则表达式进行大部分验证,它在 PHP 和 JS 上(几乎)具有相同的语法。
回答by Mike Lewis
The right place for validation is the Model.
验证的正确位置是Model。
This makes most sense because you are doing validation on the data, which is what the model represents. In terms of the CRUD updates, the model should always be used somehow.
这很有意义,因为您正在对数据进行验证,这就是模型所代表的内容。就 CRUD 更新而言,应该始终以某种方式使用模型。
If you are changing data from the view, you should have validations being checked.
If you have controllers changing data, you should have validations being checked.
And finally if you have having the model itself changing data, you should still have validations.
如果您正在更改视图中的数据,则应该检查验证。
如果您有控制器更改数据,您应该检查验证。
最后,如果您让模型本身更改数据,您仍然应该进行验证。
The only way to achieve this state is to have the validation go into the model.
实现这种状态的唯一方法是让验证进入模型。
Due to performance and faster response, after implementing the validations in the model, you should try to add some sort of client side(JS) to immediately notify the end user.
由于性能和更快的响应,在模型中实现验证后,您应该尝试添加某种客户端(JS)以立即通知最终用户。
Validation is always about the data. Why are you validating data? So you can keep the integrity of the information your storing. Having the validations at the model level allows data to theoretically be always correct. This is always a neccesity. From there you can add extra validations in your business logic and client side to make your application more user friendly.
验证始终与数据有关。为什么要验证数据?因此,您可以保持所存储信息的完整性。在模型级别进行验证允许数据在理论上始终正确。这始终是一种必然。从那里你可以在你的业务逻辑和客户端添加额外的验证,使你的应用程序更加用户友好。
回答by mjs
Validation in the model seems to be the most common approach (you end up with something like $obj->isValid()
) and this is suitable in many situations.
模型中的验证似乎是最常见的方法(您最终会得到类似$obj->isValid()
),这适用于许多情况。
However, depending on your use case there may be good reasons to perform validation outside the model, either using separate validation code or in the controller, etc.:
但是,根据您的用例,可能有充分的理由在模型外执行验证,使用单独的验证代码或在控制器等中:
- If much of the overall validation problem involves information not accessible to the model (for example, if an admin user can perform transformations that a regular user cannot, or certain properties cannot be changed after a certain date), then you might want to check all these constraints in the same place.
- It may also be convenient or necessary to apply very lax validation rules when constructing objects for tests. (A "shopping basket" object might ordinarily require an associated user, who in turn requires a valid email address, etc. A 100% valid shopping basket object might be inconvenient to construct in shopping basket unit tests.)
- For historical reasons, validation rules might change (e.g. enforcing a "gender" where previously none was necessary) and so you may end up with different versions of data that need to be treated differently. (Different validation rules may also apply to bulk data import.)
- If validation is very complex, you might want to provide different error messages (or none at all) depending upon what's most useful to the caller. In other situations,
true
orfalse
might be all that is necessary.
- 如果大部分整体验证问题涉及模型无法访问的信息(例如,如果管理员用户可以执行普通用户无法执行的转换,或者某些属性在特定日期后无法更改),那么您可能需要检查所有这些约束在同一个地方。
- 在构建用于测试的对象时,应用非常宽松的验证规则也可能是方便或必要的。(“购物篮”对象通常可能需要关联用户,而后者又需要有效的电子邮件地址等。在购物篮单元测试中构建 100% 有效的购物篮对象可能不方便。)
- 由于历史原因,验证规则可能会发生变化(例如,在以前没有必要的情况下强制执行“性别”),因此您最终可能会得到需要区别对待的不同版本的数据。(不同的验证规则也可能适用于批量数据导入。)
- 如果验证非常复杂,您可能希望根据对调用者最有用的内容提供不同的错误消息(或根本不提供)。在其他情况下,
true
或者false
可能是所有必要的。
It may be possible to handle these different use cases via arguments to the model's isValid()
method, but this becomes increasingly unwieldy as the number of validation styles increases. (And I do think it's almost guaranteed that a single "one size fits all" isValid()
method will eventually prove insufficient for most non-trivial projects.)
通过模型isValid()
方法的参数来处理这些不同的用例是可能的,但是随着验证样式数量的增加,这变得越来越笨拙。(而且我确实认为几乎可以保证,单一的“一刀切”isValid()
方法最终证明对于大多数非平凡项目是不够的。)
回答by Carl Barrett
Don't get confuse with sanitizing or cleaning the posted value with validation. You should fetch the posted values and scrub them by removing any malicious elements from the values within the Controller. Then send the data to the Model to be validated for the expected values or format. By breaking those actions into two procedures reduce the risk of malicious code to get implemented. This method works well if you are using the “trust no one input” policy; knowing some programmers can become sloppy or lazy. Another positive side is preventing your Model from becoming bloated and over worked, if so, then use a model helper to do the dirty work. This approach will also help balance your application load and improve performance.
不要与通过验证清理或清理发布的值混淆。您应该获取发布的值并通过从控制器中的值中删除任何恶意元素来清除它们。然后将数据发送到模型以验证预期值或格式。通过将这些操作分解为两个过程,可以降低恶意代码被实施的风险。如果您使用“信任无人输入”策略,则此方法很有效;知道有些程序员可能会变得草率或懒惰。另一个积极的方面是防止您的模型变得臃肿和过度工作,如果是这样,那么请使用模型助手来完成肮脏的工作。这种方法还有助于平衡您的应用程序负载并提高性能。