tags:

views:

319

answers:

4

Over the last few weeks I have been studying the MVC design pattern for web applications using PHP. Taking a broad view I understand how the pattern works and why it is a very good way of implementing any sort of web application from small or large.

As I understand it we have 3 distinct layers that talk to each other via the Controller like so:

User Input ---> View ---> Controller ---> Model

Site Output <--- View <--- Controller <--- Model

With my planned implementation I hope to have a model for each table in my database, and each model will have all the functions/logic necessary to manage this table. In turn each of these models will have an associated view. The Model and View will of course have a Controller which allows them to be used.

Now this is easy to get my head around as each single, logical action requiring the database has been covered. However, what happens when a particular action requires the use of more than one table/model?

The Admin side of the application isn’t likely to need more than one model at a time to maintain the database. The front-end or user side of the application is a different matter! Say I have a webpage that shows a list of articles for a particular section, a list of currently logged-in users and – borrowing an example from SO – site statistics such as a tag cloud.

This one page would require at least 3 models in my planned design – Article, Users and Tags.

Obviously my single controllers aren’t going to cut it. So what do I do?

  1. Create new monolithic controllers for my web pages?

    • allow me to get the results I want
    • would require a lot of duplicate coding
    • really hard to maintain if changes required
  2. Create a “super” controller that manipulates smaller specific controllers

    • allows me to get the results I want
    • would be modular so changes to one script shouldn’t affect the others
    • minimal code duplication
  3. Create [insert brilliant solution here]

I am currently erring towards Option 2. Simply because it should in theory cut down on coding as all the necessary behaviour will exist in the smaller controllers - and everything will be easy to maintain.

Perhaps it could look like this:

articlecontroller.php

<?php
    //Article Controller Script

    if($_GET['article'] = 'foo')
    {
        //magic necessary for displaying article "foo".
    }
?>

usercontroller.php

<?php
    //User Controller Script

    if($_GET['user'] = 'display')
    {
        //magic necessary for displaying users
    }
?>

supercontroller.php

<?php
    //"Super" Controller

    //magic for setting up page

    if(isset($_GET['article']))
    {
        include('articlecontroller.php');
    }

    if(isset($_GET['user']))
    {
        include('usercontroller.php');
    }
?>

As you can see, my super controller looks at what that particular page requires and includes the necessary controllers which do the grunt work. NB: The code is just a quick and dirty example :)

However, I am by no means a pro so that is why I am asking you, SO. Which option is preferred? If neither what Option 3 would you suggest? Any code snippets/examples would be lovely but not required.

If you made it this far, thank you for your time.

+1  A: 
Byron Whitlock
Ah I didn't think to take a look at what the other frameworks do to achieve this. Time to get my hands dirty and get digging!As for creating my own framework, it is just a personal project to see if I can do it. Even if it falls apart I should learn plenty along the way. :)
Peter Spain
Don't forget http://kohanaphp.com/ !
shadowhand
+1  A: 

Creating your own framework is great for learning more about design patterns, oop design and to learn more about php.

But do as Byron suggests and view the source code of some mvc frameworks just to get an idea of how they implemented the mvc pattern. Take something from the zend framework, then take something from the cakephp and in the end you'll have something that will work for you and you will also have learned something (NOTE: don't copy code, just get an idea!!)

Your super controller idea is ok but the supper controller should read the query string as arguments (check the .htaccess of Zend and the others to see how they do this) so it can treat the first argument as the controller and the rest as arguments to that controller.

Good luck!!

AntonioCS
I found that the small MVC's like CodeIgniter and MicroMVC really help when it comes to seeing how an MVC should work without all the extra junk that larger frameworks start adding. Then once you have that down you can start into more complex framework implementations. But like you say, make sure to test some frameworks before you try to build your own! It will save you lots of work!
Xeoncross
I haven't come close to implementing the specifics of how my controllers will work, so the example code I gave was just a really quick off-the-top-of-my-head example of what I was getting at. Having said that, thanks for the tip :)
Peter Spain
+4  A: 

I disagree with the direction you want to take in your model. The 1 model = 1 table design is going to hurt you in the long run.

First of all, I think you need to drop the strict notion that model == database. While that is very often true, really the model is just data - it could come from XML files, a cache, or even a web service.

Check out this excellent answer by Bill Karwin - it addresses these concerns very well.

Secondly, do some reading on the topic of fat models, skinny controllers (or thin controllers)

Lastly, just as more of an FYI, your idea of a "supercontroller" is what's more commonly known as a "front controller"

Peter Bailey
With it being such a tiny framework, the 1 model = 1 table works quite well for the most part. However I am not going to restrict myself to that completely, as I know some models WILL require more than one table.I have spent a little while reading articles by a man called Tony Marston who developed his own PHP Framework - www.radicore.org. He advocates using 1 Model = 1 Table and it is his ideas that have influenced my own designs. That's not to say his is the only way, but he does have a very robust framework and is a man who knows his stuff.
Peter Spain
I'm reading some info on his page and I think you misunderstand his intentions with a model. Here's a quote from his page on MVC "A model is an object representing data or even activity, e.g. a database table or even some plant-floor production-machine process."
Peter Bailey
Oh don't get me wrong. I know he doesn't solely stick to "one model per table", but if you keep exploring it does feature prominently.Either way as I have already said I do not plan to rigidly stick to 1 model/1 table, but where it does make sense to do so I do not see any problem with doing it.
Peter Spain
A: 

Hi all

I thought I would update this question [and accept an answer - forgot to do that :P]. I took a look at the concept of Fat Models/Skinny Controllers and I like how it is done, so I will definitely be taking that directions.

I have also taken the advice to look at some of the other frameworks and how they achieve their MVC patterns. There is rather a lot to take in! Still, I have learned quite a few new things along the way, so it was of great benefit. I may have more questions in the future, but for now I have more than enough to make a start.

Thank you all for your input.

Peter Spain