MVC - User input validation: controller, model or

2019-06-22 06:21发布

问题:

This question already has an answer here:

  • validation in mvc php 2 answers

I know questions like this one have been asked various times on stackoverflow, but even after having read those, I remain confused. I would like to gain clarity as to where form validation is supposed to be handled through demonstrating an issue with an example.

Let's say I have a form on my website, with a field that somebody fills out and subsequently submits. The model would like the controller to pass it this value correctly in order to process that value internally. The model receives the input through the function getInput, which sets the following rules:

  • The input must be of the string type.
  • The input must be of more than 0 and fewer than or equal to 100 characters.
  • The input must match the pattern of an e-mail address.

I suppose I should throw an exception inside getInput, if any of these conditions do not meet; after all, the controller passed a value that did not match the rules that had been set by the model.

Apart from the aforementioned rules, the controller (at least I am rather certain this applies to the controller) must also validate whether the input value had been set in the first place, before the script proceeds with the other three rules.

Now my question is: which of these (4) rules are to be validated by the controller, and which ones by the model? It is apparent that the controller knows what the model requests, so that it can adjust to that (and if it doesn't, it may face the consequence of an exception being thrown). On the other hand, it seems redundant to have several controllers, which all make use of the model and its getInput, validating the same kind of string so that it matches the rules set by the model. Also, if the controller firstly validates if the input is of the correct length - for example - and the model does the precise same thing immediatly after that, once getInput gets called, even more redundancy seems to arise.

In the example, the controllers and the model could be seen as a partnership with the model being a grumpy perfectionist, who is going to validate the input he gets from the controllers, regardless of the actions of these cordial partners who try hard to supply him with all his desires. But isn't such a relation terribly inefficient?

回答1:

The only thing your controller should care about is how to pass the data to the model and (optionally) how to ask it whether they're valid or not. The actual validation should be done inside of the model, because:

  • It is your model's responsibility to validate the data it is going to use.
  • You want to be able to reuse that model without repeating yourself.
  • You want to be able to able to substitute the model object (e.g. define a subclass with a completely different set of validation rules) and your controller shouldn't care.


回答2:

It depends.

Best case for DRY (don't repeat yourself) validate in the model.

However. There can be occasion when the validation you need to perform may be tailored and specific to a certain view, and although these views might have differing requirements, input from both could be valid to the model.

Often our models validate safe input based on a database schema, whilst the controller which may validate via a form, or even a method on the model, might be concerned which much more purpose specific validation.

Validating form input for your very specific purpose, and validating that a model will be correct are not always the same thing.