There's a popular believe / paradigm that states:
Thin controllers, fat models.
What this means, is that your controller should only be responsible for doing the bare minimum to make sure actions change the state of models and serve the right view in return. With this in mind, the validation should occur in your models. But... hold on for a minute. Models aren't necceseraly 1 tiered layers.
I believe among .NET programmers the following setup (or something similar) is a pretty common practice (if the scale of the project validates it):
Controller
-> ServiceLayer
-> Repository
-> DataObject
And I'm starting too like this setup more and more. Moreover, I believe this setup is very doable in a Zend Framework environment too.
The term Model is somewhat of a vague term. In the above you could consider the three last layers as your Model layer. What the three layers represent is the following:
- ServiceLayer:
Responsible for business logic. In other words: retrieving Dataobjects (Models) from the repository, tying Models together, AND validating Models before storing them, mailing a user, etc..
- Repository:
Some type of persistence mechanism (like a Database), that serves DataObjects to the service layer, and stores DataObjects back in the persistence mechanism (after the service layer validated them)
- DataObject:
You might consider this the actual Models. Preferably DataObjects have common interfaces (independant of the Repository that is), so that Repositories are interchangeable. In other words, when the repository changes from a database to an XML file from some webservice, the DataObject still has the same interface the service layer and ultimately the view can work with.
Hope this makes sense. This is basically my understanding of a more layered MVC setup right now. If anybody feels I have things mixed up please feel free to correct me.
Please keep in mind though, that not all projects dignify such a layered setup. In smaller projects you could perhaps do with just a 1 layered Model layer. In that case, validating should still be the Model's responsiblity. The controller should be thin (just for tying Model state and Views together through actions).