In part one of our series Marc Plotz lays down the
groundwork for our own MVC Framework.
Welcome to the first part of our voyage into the world of MVC. Our mission: To build an MVC framework that is:
- Self Templating
Will we succeed? Why, of course we will! Note that all the code in this article is downloadable HERE
, although I recommend actually coding this yourself if you are actually trying to learn anything from it.
Perhaps I should explain the motivation behind this system before we get started.
Being a PHP Developer interested in the Model-View- Controller design pattern, I naturally gravitated towards what are supposed to be the greatest MVC frameworks available. However, their enormous footprints, slow loading times and complicated form building systems quickly made me think twice about using them. Why not just write something myself, that does only what it needs to--and leave the heaps of needless code in the trash? A few weeks of careful thinking has lead me to the point where I am ready to tackle this task head on.
As a start we need to get a simple MVC system running, and to do that we need the following components:
View & Layout
We start with the following directory structure: Figure 1: My Project-Framework
The idea is that the core scripts of our website lie in a directory outside of the web root. This means that the main script of the website is essentially not accessible by ordinary means. Our library--the main "brain" of the framework lies outside the framework application script. The reason for this separation will become apparent as we continue.
If you are unfamiliar with the concept of bootstrapping, do not be afraid. It is simpler than it sounds. Consider the Figure 2 below: Figure 2: Index, Bootstrap and .htaccess added
I'm sure you understand that the public_html folder is our web root. Thus, going to the url http://sitename.domain, our browser is automatically pointed to the index.php file-- assuming no index.html file exists. Bootstrapping is essentially the streaming of data through the index.php file in the webroot to the application residing outside of the webroot, and back again. Having a single entry point into the website--in this case index.php, gives us complete control over the application. What we are going to do is use our .htaccess file to tell the server that no data is allowed to be served from anywhere except index.php. Our .htaccess file lies inside public_html, as illustrated in Figure 2, and has the following code inside it: Figure 3: Code - .htaccess
What this basically says is that for any request other than index.php, simply go to index.php anyway. Any variable passed after index.php in the url will make up our framework request variable that will be parsed by the router.
Next, we go to index.php itself. We need to include the bootstrap file--which is the whole point of the exercise. Basically, we do not want anything important to be done inside index.php, so we do the important stuff outside of the web root and just include it in the index.php file. For now we will want error reporting and session to work, so we will do that here too, right at the beginning. Later we will put this into a session class perhaps. Figure 4: Code - index.php
You might have noticed that I did not close the PHP Tag in Figure 3. This is not an error. Closing the PHP Tag leaves room for errant whitespace to be left after it, which can cause all kinds of problems later on down the line. In MVC leaving PHP Tags open at the end of a file is good practice, and don't feel bad about it either--it is not required by PHP anyway.
Alright, my Pet Peeve. Every time you create a new class you have to add that file to your includes file, right? And no matter whether that file is actually doing anything or not, it is included, right?
Wrong. That ship has sailed.
We are going to use PHP's magic autoloader function to find the classes that we have instantiated and then we are going to include those files according to the class name. More on that in a minute. First, in our index.php file, let's build the autoloader function: Figure 5: Code - index.php
is a PHP function that grabs all class names that have been instantiated and passes them into itself. What we then do is use it to instantiate a new class and pass our classname into that. This may seem like a lot of work just to do that, but trust me--I have been around the block a hundred times with this. It works well. You will see the proof in due course.
Now we need to create the 'library/autoload.php' file that we included inside our
function. Figure 6: autoload.php added
Now, inside the autoload.php file we create the autoload class as follows:
Click here for larger image
Figure 7: Code - library/autoload.php
The first thing that happens here, on line 7, is that we define an array of include paths. These paths are setup inside a .ini file inside the application/configs directory, and we name the file paths.ini.php, as shown below:
Figure 8: paths.ini.php added
And inside paths.ini.php we put the code shown below:
Click here for larger image
Figure 9: Code - application/paths.ini.php
Now, what the function
parse_ini_file does is go to the url passed into the first argument of the function, and read the file. The second argument, boolean true or false, tells the parser whether you have separate section in square brackets
 or not. The function returns an array which we handle on line 9. On line 10, we are removing the underscores from the class name and replacing it with forward slashes. The reason for that is our class names will map out the location of the file containing the class. So a class named controller_abstract would either be found at ../application/controller/abstract.php or ../library/controller/abstract.php. Our autoloader will look in all places listed in our paths.ini.php file until it finds the file, and then will include it.
At this point we have our site architecture basically in place, we have an autoloader that includes instantiated classes and we have a config directory with (so far) one ini file defining the site paths in it.
Next week we explore the bootstrap file more deftly, as well as why I am throwing a thing called
around in my autoload class. We will also build the registry and the router, bringing us very close to having a workable MVC model as a foundation for our Framework.
Until next week,
Marc Steven Plotz
Marc Plotz is a Senior Web Developer for a major South African web development company and regularly writes articles on various topics for online web development article publishers. He specializes in the development of enterprise-class web applications and rapid application development frameworks. He lives in Pretoria, South Africa, with his wife and two children.