Home arrow Blog arrow MVC Problems in PHP

MVC Problems in PHP

Once people are aware of it, few disagree with the general idea of MVC. But differing interpretations and practical implementation problems tend to create disputes. I want to discuss the particular problems of creating HTML in PHP.

First a quick review of what MVC was originally about. The idea was that at the heart of a software system there is something that could well be described as a model of the problem the software aims to solve. Assuming we're committed to OO principles, the model will consist of objects that reflect the entities that belong to the problem area. One part of the principle that often gets lost is that it is central to the problem domain (or model) objects that they have behaviors, possibly quite complex ones. The model classes are therefore able to provide a solution to the problem - except that they have no means to interact with the outside world, but live entirely inside the computer.

[Note in particular that the idea of a model object is not derived in any way from something like a row in a relational database table. The question of making the model objects persistent is secondary to the creation of the model and should not be the starting point. Although a practical approach to designing web systems has to take account of the fact that the most readily available storage mechanism is the relational database. Software that maps database table rows into objects is not itself the model, but is a useful tool for use by model classes, particularly if it does not constrain the ability to build extensive behaviors.]

This brings us up against a prime motivation for MVC - we need to have ways to see representations of the model, that is to say we need views. And it may often happen that we want to look at the model in a variety of different and overlapping ways. This does not alter the requirements on the model of the problem, because it has no impact on the functionality of the model classes other than their ability to provide information about their current state. Moreover the way we want to "see" the model can vary independently of any need for change in the model itself. So it makes sense to have views as a separate category of software from the model.

Now we are nearer to having a usable system, but something is lacking. We can see the state of the model and it has behaviors that solve the problems that are at stake. But we have no way to interact with the model. Thus arises the need for controllers. Controllers are software that accepts external events - often user requests but possibly requests from other systems, timers, etc. The controllers need to marshall the objects of the model, make requests of them based on input received, and create output using the views.

An important point about view classes is that they are conceived as being software needed to create a visual representation of the model. They are expected to include program code. The idea of a template that is specifically geared to the creation of HTML is a different, although related, matter. The MVC principle does not require a separation of PHP code from HTML, even if limiting the mixing of the two may be helpful for web designers.

That brings us to being able to review the problem of HTML creation. There are several ways to do it using PHP. One is to flip in and out of PHP - whenever you are outside PHP tags, whatever code is on the page is simply rendered to the browser. Another is to use the echo statement. This can be done with ordinary strings, or it can be done with the PHP "heredoc" structure. Heredoc has the considerable merit of allowing extensive HTML to be written while allowing the insertion of values from PHP through the inclusion of variables. There is enough flexibility in PHP5 heredoc that "variables" can actually include a call to an object method.

Before continuing, a quick digression into widgets. One might have supposed that HTML creation would be similar to other visual development problems, and therefore be solved by the growth of widget libraries. This has not happened, and is an approach disliked by many web designers. It seems that the nature of HTML is such that it is hard to create useful widgets. So much variation is needed in the exact HTML to meet a particular requirement that the parameters become excessively complex, undermining the value of a widget. It is so often easier to write the HTML than write a complex call to a short function that, so far at least, widgets have not been popular in HTML generation.

So, if we are interested in creating substantial amounts of HTML in as clear a way as possible, we seem to be limited to two options: either jumping out of PHP and coding the HTML outside of PHP or writing PHP heredoc to contain HTML. Both have drawbacks that seem to preclude an ideal solution.

First the drawbacks of jumping out of PHP. A problem with this approach is that within the HTML there is the need to jump into PHP whenever the value of a PHP variable is needed. The code looks a mess because of the clumsy PHP tags. Another substantial drawback is that (without the added complexity of output buffering) code outside PHP is sent immediately to the browser, whereas it is often useful to build a page out of a number of strings that are only put together and output at the last moment.

Perhaps the biggest drawback of jumping out of PHP is that whenever logic is required, it is necessary to jump back into PHP. The mixture of PHP logic and HTML soon becomes extremely difficult to read and figuring out what is going on becomes arduous. Developers typically rely on indentation to show program logic, but with the addition of PHP tags and the presence of much HTML (which has different indentation requirements) makes a mess of the page. In the end, the code is largely unreadable.

The drawbacks of heredoc relate to the need to break up the HTML into sometimes quite small chunks, breaking the flow of HTML creation. Within a heredoc section, the most powerful option is to call a method on an object. That can be used where some HTML is to be included conditionally. This requirement arises repeatedly where, for example, if a string intended as a title is empty the HTML heading tags should be omitted, not just the title text.

Another requirement to take things out of line is if a block of HTML is going to be used more than once. Following the DRY principle (Don't Repeat Yourself) the HTML should be coded only once, which means that it cannot always be shown in line where it is used.

My own preference at present is to use PHP heredoc for most HTML. Each piece of HTML is then easy to read and easily edited. The drawback is that it may be necessary to follow up a number of method calls to find all the HTML that makes up an application's output. But there seems no ideal solution that would eliminate all the drawbacks. For this reason, I am distressed to see claims that a particular style of development is the right one, or attempts to enforce one interpretation of MVC as being the "correct" one.

#128009 • 10/15/2010 5:18pm by Martin Brampton • Vote: Up votes (291) Down votes (174)