Etzeitet
Etzeitet

Reputation: 2125

Creating and combining controllers in an MVC PHP web application

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.


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.

Upvotes: 0

Views: 1468

Answers (3)

Peter Bailey
Peter Bailey

Reputation: 105888

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"

Upvotes: 6

AntonioCS
AntonioCS

Reputation: 8496

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!!

Upvotes: 1

Byron Whitlock
Byron Whitlock

Reputation: 53861

You should really take a look at the PHP MVC frameworks out there. They have figured all this stuff out already. They will have URL routing (/article/edit/1), good MVC seperation, and great docs to help you through it. So instead of worring about how to call the view from the controller, you can think about your application. I've personally saved tons of time when i finally took the dive.

There are many others out there.

Creating a PHP MVC framework from scratch just probably isn't worth the effort. If you are dead set on reinventing the wheel, you should at least take a look at the design considerations that went into these frameworks for inspiration.

Upvotes: 2

Related Questions