Food for thought: utilizing models in MVC

December 6, 2008 – 1:14 pm Tags: , ,

“What is a model” and “Is Zend_Db_Table a model” seem to be asked once in a while on #zftalk. Frameworks say they have a full model available, thus they are MVC frameworks

ORM libraries say they generate models. It seems the ActiveRecord pattern has become somewhat synonymous with model.

Pádraic Brady wrote an excellent post on how models are misunderstood, and how this poor understanding causes “fat stupid ugly controllers”, as he puts it.

Here are some thoughts on actually putting Pádraic’s advice into practice, and some examples in context of the Zend Framework.

Pádraic writes that the best controller is one that doesn’t need to exist. This is true: many pages simply need to display certain data fetched from the database (or other data source), or maybe simply a static page. Why would you need a controller for this?

At this point you may think “to pass the data from the model to the view, of course”, but that’s not really the case. If you’ve seen any of those diagrams which explain MVC, you may have noticed that line which goes from the view to the model to show that views could access models. In the case of Zend Framework, you could use view helpers for this.

I have to admit that I’ve done actions in my controllers just to get some data from the database. It’s so easy! Just grab data, assign it to the view, and have the view output it… Compared to having to think of a good way to access the model from the view. Maybe it would be time to break from status quo?

However, there are some questions in regards to having the views fetch data on their own. Very often the fetched data would depend on the parameters passed in from the URL, such as the ID of the document, the page of the list or such.

Many frameworks don’t implicitly allow access to the request in the view, so would accessing such variables require the intervention by a controller? Or would this too be a case where you would utilize a view helper?

In a sense, the parameters passed from the request are also parts of a model: the request model. The request model could be instanciated based on the request object itself, and it could perform validation on the data. Alternatively, you could set up your routes so, that they won’t match any requests with illegal data, by providing sufficient regexes for validation.

To achieve most flexibility, it would probably be a good idea to keep parsing any parameters from “outside” inside your controllers. Imagine a case where you for example displayed a specific user’s details. The user’s ID could come in from the request, and passed to the view from the controller.

In the most typical example you would see for the above, you probably would have the view called the same as the controller’s action. It could be “user” or something. But if the view itself could access the user model, it wouldn’t need to depend on the controller. So you could actually have some completely different controller render the user’s information if it needed to, by simply passing the user id to the user view. Or you could even have some other view include the user view as a partial, passing the user id to it.

So how would you access the models in your views then? You could write a view helper for each of them, or instanciate them in your views.. but that could be a bit tedious and sometimes not the best approach.

Instead, a single view helper for getting and instanciating models could be more convenient. It could work in a bit similar way as the service locator pattern does:

<?php $this->getModel('MyModel')->getAll(); ?>

Using this approach, the views would not need to know how the models are created, or what model they are actually even dealing with. You simply would program to a specific interface, assuming that by calling getModel(‘MyModel’), you would get something that conforms to MyModel_Interface, or something like that.

In closing

I’ve been thinking about these for a while already, but Pádraic Brady’s post got me thinking about it a bit more.

In all this, there’s still certain things that need to be kept in mind. Caching, for example. If you wanted to cache specific SQL resultsets or such, it would need to go somewhere where it would happen without interaction from the controller.

And finally, bear in mind that I don’t think these are necessarily the best approaches to solving this “problem”. Please comment what are your thoughts on this matter.

Additional reading on the topic: J2EE View Helper pattern, J2EE Dispatcher View pattern and Pull vs Push MVC architechture on Guy Rutenberg’s blog

Share this:
  1. 12 Responses to “Food for thought: utilizing models in MVC”

  2. Here’s a fun thing I just realized

    At first, you write a mess of spaghetti HTML+PHP. Then you are told you need to separate business logic from your templates, so you start using a template engine and then do $tpl->foo = ‘bar’; all over the place.

    Then you are told you should access data from the template. Kinda like going backwards a step :]

    By Jani Hartikainen on Dec 6, 2008

  3. Happy it got you thinking 😉

    Here’s an idea to contemplate – can Models also take charge of specific user input validation when the input is clearly Model related?

    In such cases you only need to bear in mind that views should never validate. Either the Model does or a Controller.

    It’s great hear other perspectives on what I wrote!

    By Pádraic Brady on Dec 6, 2008

  4. interesting idea. I’ve been tackling this issue too with View Helpers. But right now, I make the controller provide the data by calling the Model layer (propel db). Then it provides the data to view which then passes it to the helper that deals with it.

    This is not perfect I know… but it seems right that the Controller controls what data to get. The view and helpers knows how to render it but do not get involved with the logic behind data validation, fetching specific filtered views etc…

    By andre on Dec 9, 2008

  5. It’s very interesting.

    I’m a bit of newb to MVC, and ZEND. But there is a danger of this all becoming an intellectual wank.

    If the concepts with MVC become so contorted and complicated that no one really understands the pattern then it’s failed.

    Instead of increasing transparency and efficiency in the ZEND MVC there seems to be a lot of chat about view-helpers and action-helpers and an application with sprawling code and directories all over the place. This seems overly complex to me.

    If the ZEND MVC concepts cant be explained in a straight forward manner then something is wrong.

    The answers to the question “what is a model” usually confuse rather than clarify. Thats why is gets asked so much.

    By firecall on Dec 11, 2008

  6. firecall: I agree about the confusing part.

    I don’t think MVC is really confusing, but it’s just a programming design pattern, and design patterns are higher level programming concepts. Things you learn in your last years of a degree… and since PHP attracts lot of atypical programmers, I think these concepts can be easily confused.

    That being said, it’s not easy to follow MVC perfectly, but you’re trying to improve code reuse. So think of insolating each layer so that each one could theoretically be used in different applications. This usually involves reusing helpers, some views and then adding application specific logic to functions that extend… still, it’s hard and requires experience. I would say all programmers constantly work towards this…

    By andre on Dec 11, 2008

  7. I gave up on using the Java site for design patterns in regards to PHP a few years ago simply because there are too many differences between the platforms – a lot of the patterns described on the Java site simply do not apply to PHP.

    But there is that many PHP specific resources now available that you now do not need to refer to the Java site (thankfully).

    But each to their own…

    By Les on Feb 9, 2009

  8. All the confusions would be gone if people had read the MVC from the original inventor :)
    MVC is the acronym of Model-View-Controller. Though MVC Frameworks seem recent (Zend Framework, Symfony, ASP.NET MVC,…), MVC is actually an old concept originally crafted in 1978-1979 at Xerox Parc by Trygve Reenskaug.

    By learnnewprogramming on Dec 15, 2009

  9. Bypassing the controller is stupid idea altogether, just like accessign models from views. Or using routes to validate data.

    Controller’s job is to control the flow of data, it takes in the request parameters, fetched data accordingly, and passes it to view.

    View is supposed to be really dumb data output layer, was it visual, or say XML result for a REST query.

    Controller does not have to be fat to do it’s job, infact it could be something like this in the case of viewing invoice:

    public function viewinvoiceAction() {
    $invoiceId = $this->_getParam(‘id’);

    $userInvoicesModel = new Model_User_Invoices();
    $invoice = $userInvoicesModel->fetchEntry( $invoiceId ); // Validation done in model like it should be!

    $this->view->invoiceId = $invoiceId;
    $this->view->invoice = $invoice;

    (i hate PHP + HTML mashup for being confusing looking, i prefer smarty for simple visual output)

    preferred error output here
    } else {
    include ‘invoices/view-invoice.php’; // output

    The model is going to be “fat” so to speak, but that’s how it’s supposed to be: All business logic is there, no data flow control, visual stuff etc. It does validation, caching etc. all on it’s own.

    Controller is just like it’s supposed to be: Controlling the flow of data.

    View is just like it’s supposed to be:
    Viewing the data results accordingly.

    Some flex tho: You could choose in controller dependant upon if there’s errors to pass it to the error controller and display normal error page instead etc. On simple cases, i see doing particular view exceptions simpler.

    Just remember: KISS. Keep It Simple, Stupid. and you will have the cleanest, most beautifull and easiest to maintain code.

    By Aleksi on Feb 15, 2010

  10. Hmmph, somehow the view portion got messed up.

    It was supposed to be:

    if ( isset($invoice[‘errors’]) ) {
    foreach($invoice[‘errors’] AS $thisError) {
    // Your fav method / style to output errors
    } else {
    include ‘invoices/snippets/invoice.php’; // output

    By Aleksi on Feb 15, 2010

  11. Padraic: Model should always do the validation, it’s models area to do so.

    Andre: You are actually on right track with your methods. Views just for rendering the data, controller just for controlling data flow, and model for all data handling and business logic.

    And yes, MVC is very old design pattern.

    By Aleksi on Feb 15, 2010

  12. Thanks for a very thorough comment, Aleksi.

    By Jani Hartikainen on Feb 15, 2010

  13. First of all, thank you for the great article Jani!

    Regarding @learnnewprogramming:

    As is no longer available, I did some digging to find the original MVC docs by Trygve Reenskaug.

    Here’s the link:

    By Jesse Burns on Oct 9, 2013

Post a Comment

You can use some HTML (a, em, strong, etc.). If you want to post code, use <pre lang="PHP">code here</pre> (you can replace PHP with the language you are posting)