Emiel Bruijntjes

PHP and Model View Controller: impossible!

Written by Emiel Bruijntjes on

A couple of years ago I encountered a PHP framework that claimed to be based on the “Model View Controller” (MVC) pattern. When I first read about this framework, I was a little surprised because PHP is not at all an appropriate programming language for making MVC applications. At that time, I expected that this was just a mistake by someone who didn't know the true meaning of MVC, and that he or she would soon be corrected by more experienced developers. This did not happen. In fact, nowadays there are many different PHP frameworks that all claim to be MVC – but as far as I have seen, this claim is still as outrageous as it was for the first would-be MVC framework that I saw. PHP and MVC are not compatible with each other, and it is about time that we stop calling each PHP framework MVC.

An introduction to MVC

The Model View Controller pattern predates to a time before we were even building web applications. It was invented in ancient history when we developers were still building windows or even console applications.

An MVC application gives you the power to open multiple screens (views) at the same time that are all connected to the same data (the same model, for example a text document or a spreadsheet). When one utilizes one view to make a change to the data, the contents of the other views are updated at the same time. These instant updates are triggered by a controller object that is constantly alive, and that keeps track of all open views to notify each of these views when the underlying data changes.

Today one can still see MVC in action. For example, most operating systems offer various controls and dialogs to change the sound volume. There is a small sound control in the task or menu bar at the top or the bottom of the screen, you can adjust the volume by pressing the volume control buttons on your keyboard and you can open an advanced dialog window to configure all sound settings in detail. When you open all these user interface elements at the same time, you will notice that the sliders in the dialog window automatically update when you adjust the sound settings from the task bar or by pressing the keyboard keys – and the other way around. This is a text book example of the Model View Controller pattern: the model is the actual sound setting, the views are the different dialogs and control elements, and the controller is the object that connects all those elements, and ensures that the views are all updated when the sound volume is changed.

To provide you with another example, try opening a spreadsheet or word processor. These are programs that allow you to open a second or third window with the same document, and/or that allows you to split the screen into smaller parts that all show the same document. If you alter the document or spreadsheet using one of the views, the other views are updated simultaneously.

Building such MVC programs is (of course) more complicated than making programs that do not have this feature. And besides that, most everyday users do not even use those MVC features (in fact, even I hardly ever use it). That's why most developers choose not to enable MVC for the software they make. Back in the days when I was still a student making desktop applications, building MVC software was mostly done to boast, rather than to add a feature that would really be useful.

PHP and MVC

MVC in a web context is difficult. Let's start by setting up a use case. The views for a MVC application in a web context are of course browser windows that all show the same sort of information, for example a page with special offers from a web shop. The model is the actual pricing information in the database. The controller object should then have a list of all open views (all open browsers), and notify each one of them when one of the special offers changes, or new offers are added.

Traditionally, a web page is a simple HTML file that is downloaded from a web server. After a browser has loaded such a file, it closes the connection to the server and from that moment on, there is no way for the server to ever initiate contact with the browser again to inform him that the file that he has just downloaded might have become outdated. There are of course some tricks, but they all require client side scripting (javascript). If you only look at the web from the perspective of the server, there is no way to ever update a view that has already been downloaded. A server side controller that keeps track of all views and that notifies them is therefore not possible.

And then I stumbled across MVC and PHP. I was surprised by it, because I didn't know better that such a thing could not be achieved with a completely server side programming language like PHP. I was very curious how they managed to build a PHP framework that can update multiple views, open on multiple browsers on many different computers when the underlying data changes. How could they build that by just using PHP? The answer: they couldn't.

Yes, one can of course make pages that automatically reload once in a while, or that update their content every now and then. But that all requires client side javascript. And one needs to implement it by doing periodic ajax calls, or use tricks like slowly loading keep-alive connections or using websockets – there is nothing wrong with doing that, but that are technologies other than just PHP. An MVC framework fully implemented in PHP is impossible.

The most elementary task of an MVC framework is to notify all open views when the model changes - and this is exactly what a pure server side technology like PHP is not capable of doing because of the very nature of the web. The PHP frameworks that claim to be MVC are simply cheating: they claim to offer a certain feature (MVC) that they do not have! They may be frameworks of high quality that do a very good job at seperating user interface code from the data layer and the business logic – but that has nothing to do with MVC. If you really want to build an MVC web application, you need much more than only PHP.

If you realize what a PHP script actually is, you wonder what those developers were even thinking when they tried to implement MVC in PHP. A PHP script is nothing more than a simple program that takes a small amount of input (a HTTP request) and that turns this into a HTML string - and that all in a split second. How can you even make a controller object that only lives for a fraction of a second, much shorter than the views it is supposed to control? And why would you go through the hassle of setting up a controller that keeps track of a list of active views – if your program only runs for a fraction of a second. That would be insane.

Why do MVC PHP frameworks exist?

I of course can not look into the minds of the developers who started the PHP MVC frameworks and do not know the real reasons why those frameworks claim to be MVC. But I can guess. I think that it is related to what I have written before about MVC being a way to show your skills to the world. Writing an MVC application is a challenge, and the PHP developers who built those frameworks may have fallen for this. They must've heard about MVC and that it is cool and have decided to implement this pattern in PHP – completely overlooking the fact that MVC cannot be implemented in a server side language.

So, how do you make a fake MVC framework in PHP? The start is easy. You first separate the user interface code from the data and you name these classes 'view' and 'model'. Lets forget about the fact that separating data from the user interface is not really a feature of MVC – it is a fundamental principle of programming – and that MVC is all about the controller that is able to notify all current views when the model is updated. At least you now have a 'model' and a 'view' class so you are almost done with your MVC framework.

The final step is to make a class that connects the model and view objects with each other. For this class you use the inappropriate name 'controller'. The name 'dispatcher' or 'http_request_processor' would be much more suitable, but by naming it 'controller' you find yourself in the nice situation that you have three classes named 'model', 'view' and 'controller' and that it is just like you have implemented the MVC pattern. Your framework lacks the only meaningful feature of MVC – being able to outdate active views, but that is only a minor detail.

It looks like the framework developers think that just giving a name to a class is enough to implement a pattern. If you want to use the singleton pattern, you simply name your class “Singleton” and you have that pattern. And if you want to use the observer pattern, all you need to do is use the name “Observer” for your class. These examples are of course ludicrous, but for MVC frameworks it looks like this is actually happening, the classes are indeed named “Model”, “View” and “Controller” and the frameworks claim to be MVC, while in reality the frameworks are not capable of doing what is required by MVC.

An alternative

Let's stop speaking about MVC if a framework is not. For true MVC we need a central long living controller object that has a list of all active views, and that is capable of notifying these views when the data (the model) is modified. The views in their turn should then automatically update themselves.

The current PHP frameworks that claim to use the MVC pattern, but that are not capable of doing what I described above (and this is true for all frameworks that only have PHP code and no client side code) should stop claiming to be MVC, and use a different name. An alternative and more appropriate name would be Model-View-Dispatcher: it seperates the model from the user interface, and there is a dispatcher object that processes requests and that sends back the appropriate view.

MVC for a web framework is not completely impossible, but requires other technologies like client side scripting and server side programs that run for longer than a split second (like PHP scripts do). Let's reserve the MVC terminology for future frameworks that offer true MVC features, and not use it for PHP frameworks that only seperate the data from the user interface code.