The MVC architectural pattern is a smart and bright way of developing web-based applications. The acronym MVC stands for Model, View and Control: these are the three components that, according to the pattern, every application can (and should) be divided into. I would actually state that MVC is "the ultimate" way of developing apps but since IT is such a fast-growing/evolving discipline, I won't dare being so bold and just say that it is certainly a topic every good developer should spend some time on.
This article will try to briefly expose the basics of the MVC pattern and put forward an alternative template management system based on the duo XML/XSLT. Many MVC implementations in php are actually quite fuzzy in the way they manage the Views layer. Most of them partially fail in separating the markup from the programming language and there are often some residual bits of php code here and there (in the view files) that really annoy me a lot! ;-(
As I'll show you in a while, it is absolutely possible (and wise) to keep the two things clearly distinct and obtain a complete separation of presentation from logic. OM!
The goal of MVC pattern is, as stated above, to identify (divide and develop separately) the 3 layers we have briefly outlined. Let's try a simple definition for each of them:
It's also probably worth noticing that the 3 layers correspond to as many differently skilled developers. A pure php developer will actually be responsible for the logic of the application (Controller layer), a more db oriented (php) developer will take care of the implementation of all the Model layer (db structure and performances as well as data tranformations/alterations) and finally, (which is actually my favourite!) the front-end developer will produce and maintain a highly responsive, accessible, usable and cool interface (View layer). All in all a really nice and friendly environment don't you think? Keeping the 3 levels separate also corresponds to allowing the 3 developers to work freely in their relating environments without running the risk of editing by mistake pieces of code that are outside his/her jurisdiction! It sounds good, doesn't it?
Ok! We have briefly identified the most important elements of the MVC pattern, well done. The next step will be the implementation of a very silly application that allows the user to:
Basically it will be a 2-states application (either "articles list" or "chosen article") that will allow us to have a closer look at each of the 3 components forming our MVC application. Let's start with the front controller then: the pumping heart of our project!
All the sub-controllers in our application will be coordinated by what's commonly called "the front controller". Such component decides what sub-controller to evoke on the basis of the input sent to the server by the user (in PHP this information is conveied via the superglobal array $_REQUEST). The front controller is therefore the entry point to our application as all the requestes are processed by and aimed to this piece of code. Here's an example of a possible front controller:
As you can see the class is defined and the static method "dispatch" is run straight away. This method composes the name of the sub-controller at runtime (using the input $_REQUEST['action']), instantiates it and finally fires its exec method (which must be defined in each sub-controller class). Ideally the piece of code above should be placed in the file index.php. Clearly the class frontController should be able to access all the sub-controllers (each of which is gonna be a class), so before instantiating the front controller it is essential to run a require_once that points to the file where all the sub-controller classes are stored. Something like this should do:
Ok we have the dispatcher now. Let's first have a look to the sub-controller managing the "articles list" state and then move on to the "single article" one.
As we said each of the sub-controllers must be a class and have a public method called exec. Note that this sub-controller will be called defaultController and it will be therefore triggered by simply pointing to index.php without passing any other additional parameters (in fact no specific article needs to be identified). Here we go:
The class includes the file containing the Models (we will talk about this layer in a while), instantiate the relating Model and run the getXMLData method in order to obtain the list of articles. The interesting bit here is the format the data are given back in and what we actually do with them. As the name of the method suggest (getXMLData) the data are gonna be formatted in XML. That is the starting point from which we will be able to implement our brand new XSLT-based template engine. I won't go into many details about the sub-controllers but, as you can easily figure out flipping through the code, I have created an xml document and populated it with the string obtained from the Model. Also I created a xslt processor and fed it with the xsl file representing the View for the articles list. Finally I fired the method transformToXML() that tranforms the xml into HTML using the set of tranformation rules specified in the xslt file.
All the natively implemented classes at stake here belong to the DOM exstension (which comes out of the box with php5 and relies on the great libxml2 and libxslt). In the php website you can find loads of info about he functioning of these classes/methods. Instead, for a good and exhaustive guide on xslt, have a look at this tutorial (sorry but I really don't have time to talk about xslt here!).
As promised at the beginning of the article, the complete separation between php (programming language) and presentation (xslt) has been succesfully achieved. The front-end developer will be working ONLY on the xsl tranformations regardless of the logical layer managed via php. Also, during development phase, it might be useful to print a commented out version of the xml string containing the data from the db. This will give the front-end guy the opportunity to know what the data available (and therefore retrivable via xsl) are without bothering to open the php files where the xml is effectively created.
Let's now move on to the Model layer and see what it actually does. As well as for the xslt tranformation process, I won't go into many details and just show how the application should ideally work.
The model layer is going to return the controller a xml-like string that is roughly going to look like this (I formatted it to make it more readable but all the return characters woulnd't be there):
Now that the sub-controller can finally rely on a bunch of data in xml format, we are going to present the xsl file in which all the transformation process is specified. As I said this is not a xslt tutorial so no further explanations on the following code will be given. Here we go:
The code above should be fairly straightforward. One little thing that certainly deserves to be pointed out is the link tags wrapping the article titles in the list. The href attribute contains the parameter idArticle (which corresponds to the article's id in the db) and the name of action to be activated: article (which becomes articleAction after being processed by the frontController class). Clearly this dinamically-created links will all lead to a specific article specified by the id included in the URL. That it is to say that they will all trigger the other state of our application. Let's have a closer look ...
Here's the sub-controller displaying the title and the content of the chosen article (the article specified by idArticle in the querystring).
This time we pass the Model layer the parameter $req['idArticle'], which will be used in the query extracting the data about the article. Here is the Model:
Being the id passed unique in the db (ideally it's the primary key of the table containing the articles) we are going to obtain an xml-like string containing 1 single node, like this:
Finally, the xsl that we need to tranform into HTML the xml bit we have just obtained, should roughly look like this:
Easy no? As you can see I have also added a link to the home page, namely the interface generated by the sub-controller defaultAction, so that there is a kind of ease of access throughout the whole application in case you wanted to implement and test it.
The articles has shown an oversimplyfied version of the MVC pattern. Clearly many additional parts should be add in the attempt to obtain a professional and flexible solution fitting all the possible requirements. But my purpose here was merely scholastic and my intent was simply to make you guyz touch with your own hands the foundation of a MVC pattern implementation. Hope you enjoyed the long article. Here you can also find a zip containing a copy of the code used in the article. Cheers
Hey nice article. I haven't done much XSLT in my life but it looks like a good way of separating stuff. Thanks
A really good article ... Thanks SOOoo much :)
MVC and XSLT in the same word... great!