Pragmatic PHP MVC

July 6th, 2006

I recently completed an A-Level project in PHP. It went quite well, but I was still keen to improve on my design methodology. To a “weekend silicon warrior” this may seem unnecessary, but I assure you the bigger applications you write, the more consideration you’ll find yourself putting into the design to stop headaches later. Specifically I was interested in MVC programming, as I was really annoyed at the repetition of code involved in generating other views in my web-application (part of the A-Level project involved generating PDFs). So I’ve been hanging around Sitepoint’s PHP Application Design forum and reading various sites such as PHPPatterns trying to glean information.

Suffice to say a whole new vocabulary opened up to me. It was a bit daunting at first, but I wholeheartedly recommend learning at least some of it. The “pattern” names themselves are essentially just ways to easily identify abstract coding methodologies so everyone knows what they’re talking about. Basically this allows people to drop acronyms like “MVC” into normal conversation, even though it in itself isn’t anything, it being an idea composed of three coding practices:

  1. Model: Where all your “business” logic is stored.
  2. View: How the output of the model is displayed (going back to my little PDF generation problem).
  3. Controller: The thing that glues the model and view together according to what the user wants.

Unfortunately definitions like that are always up for dispute and alteration/addition but essentially as long as you always keep in mind the goals behind code separation you can’t go wrong; as MVC is more a frame of mind than set-in-stone rules. It’s best to keep a strictly pragmatic view when deciding what’s best for your application: just because something looks cool doesn’t mean it will instantly benefit you. Going back to my PDF generation problem I wanted to use MVC so that I could:

  1. Generate raw output from my business logic. (Database queries and things)
  2. Give that to the appropriate view. (According to user request HTML or PDF)
  3. Not repeat any business logic.

Which fits into the MVC paradigm nicely. Obviously if you had a relative simple PHP application, like a mailer, then you wouldn’t want to add all the extra MVC bother. A signature I saw somewhere on Sitepoint springs to mind, it was actually referring to XML, but to paraphrase regarding MVC:

I once had a problem, so I decided to use MVC. Now I have two problems.

However now I tend to recommend you lean towards MVC as it simply means that your application will be more flexible if you did want to include another view/interface to your system. This can be especially useful in–surprise, surprise–web applications where you must keep up with the times to allow users to access your content in different ways, which we’ve seen with the advent of RSS etc.

Unfortunately things are rarely a simple case of decide and go with it, as I found out while hacking on the backend to my latest website project. The problem I had was to do with the way I was handling user authentication through sessions. Before reading on, I suggest you have a look at some notes on Front Controller implementation with PHP to fully understand my predicament. See also diagram on the right.
Diagram showing flow chart for the front controller

Basically I wanted something different from the Zend framework’s all requests being routed through one file approach (see comment) I wanted to split up the Front Controller into smaller chunks. My sentiments are summed up by a post to a Sitepoint thread regarding the subject. Summed up my gripes are:

Diagram showing the Page Controller pattern
Those points are basically rehashing what was in that post. My “solution” to this problem was to use the Page Controller pattern. See the diagram left.

“The Page Controller has one input controller for each logical page of the Web site.”

However that approach generated some problems for me. The reason that the Front Controller is a popular pattern is that you can call Intercepting Filters. I was getting some problems without using them:

However I managed to find a lovely piece of code that looks at Intercepting Filters in a very concise way. The use of chained methods is reminiscent of Linked Lists if you’ve ever done Computer Science (I haven’t, I’ve just read about them).

My current system uses Page Controllers with those Intercepting Filters, but instead of having the Intercepting Filter classes output anything, I instead just put a header redirect to a page more suited to dealing with the new task(s). For instance if a user needs to be authorized to access any particular page, the Intercepting Filter class checks, then if they’re not header-redirects them to the appropriate page (login.php).

When the system is all up and running in hopefully a month or so, I’ll post some code.

2 Responses to “Pragmatic PHP MVC”

  1. Jayson Minard Says:
    July 7th, 2006 at 8:42 pm

    Hello Alex,

    A few of your points about the Zend Framework front controller are not accurate.

    First, you can have multiple boostrap files (i.e. index.php), it is up to you and your rewrite rules to decide that. It is convenient for many people to have just one universal one, or a small set for major functional areas of their site.

    Second, the controller does not need to know about every action ahead of time. It dynamically discovers the class that matches the controller name from the URL, then dynamically discovers the action method matching the action portion of the URL. Nothing known in advance, just discovery by naming convention.

    Lastly, the new RewriteRouter gives you even more control over the mapping and handling of action dispatching. But if you select to use the default routing, you can stay with the dynamic know-nothing-in-advance model.

    – Jayson

  2. Alex Says:
    July 7th, 2006 at 10:18 pm

    Parts of the article have been ammended, comment again if there is anything else.

    Zend Framework is the only framework I’ve ever spent any time on, so I suppose some gripes about Java styled PHP frameworks filtered in there. Apologies.