Roll Your Own PHP Framework

An introduction to building your own PHP framework using the MVC design pattern.

Building your own PHP framework from scratch can be a great learning experience, not only will it teach you how to use OOP design patterns, but you will be left with a great little framework at the end of it which will be lightweight, easy to customise and will save you time in future projects.

This tutorial aims to answer questions such as why use a framework?, and how can design patterns save me time? It is aimed at the intermediate level web developer who has an understanding of OOP but doesn't yet use it to it's full advantage. In this part we aim to explain some of the ideas that underpin the framework we will build a very basic OOP site using the MVC design pattern.

Future tutorials will expand on this basic structure, and will add lots of other functionality.


Upgrade your code to OOP

As you evolve as a programmer you will no doubt move from writing procedural code (where the flow of logic runs from the top of the page to the bottom) which has lots of code duplication to grouping your code together into re-usable functions, this code re-use is oftern referred to as the DRY principle (Dont Repeat Yourself) and this is one of the cornerstones of a good programming technique as it reduces duplication and with it the possibilities for errors.

OOP (Object Orientated Programming) takes the DRY principle to the next level, by grouping your code into classes of closely related methods and properties (functions and variables to the procedural programmer) code is re-used more effectively and duplication is reduced even further.

A lot of developers never get beyond this stage, as using a mix of procedural and basic OOP code can get you a long way, and often they feel that the OOP box has been ticked and their code is "good enough". This is a shame as OOP can be a very powerful tool and there can be a lot of advantages to using it correctly.

The problem with using OOP to its full potential requires you to adopt a different approach to how you write your code as it's a lot more abstract than procedural code and this can be hard for a lot of developers to get their heads around. So, if this is your first foray into the world of OOP you may find it a bit of a brain melter, but stick with it, we are going to go real slow, and with any luck you may just have an epiphany.

The deeper you get into OOP the more you will hear about design patterns, fight the urge to run away, these are here to save you time, some of them can be dead simple and you may have already used them without knowing it. Put simply design patterns are solutions to common problems that you will come across when writing OOP code and are here to save us from re-inventing the wheel, MVC just so happens to be one of those design patterns.

Why use a Framework

A framework is essentially nothing more than a library of code, that has an easy to use interface. Using one will help you to write better code and to write it quickly, which has got to be a good thing as it leaves you more time to drink tea. Infact you may have already used jQuery which is an excellent JavaScript framework which takes all the pain out of writing robust cross browser compatible code and means you can spend more time concentrating on the fucntionality.

MVC what?

MVC stands for Model View Controller, it's an OOP design pattern, but dont let that put you off, it is a lot easier to understand than you may think.

The problem that MVC pattern solves for you is to do with the seperation of concerns. Woah that sounds heavy, but all it means is that each section of code, the Model the View and the Controller have their own jobs to do, and by keeping them seperate the system as a whole can be efficiently expaned, modified and re-used.

MVC is good for building a framework that you plan on using across multiple websites, or for a single large scale project, but it is probably overkill for a one-off website or small scale project.

Do we really need yet another PHP framework?

No, we dont, you could quite easily just jump straight into using one of the fantastic PHP frameworks that are already out there such as CodeIgniter,Symfony and Yii , but you'll never really get a good understanding of how it works, you'll just learn what knobs to twiddle and what levers to pull in order to make things happen, and this isn't good in the long run. What would happen if the framework stopped being supported and you needded to tranfer all your code to a different framework that had different syntaxes and different ways of working, you'd be starting over again from scratch. If you knew the fundamentals of how all these frameworks work you'll be in a much better place when that time comes.

Put simply, building your own framework will be a great way of learning new techniques, and because you dont have thousands of users to support with a wide variety of needs, you can write just the bits you need, meaning your own framework will be lightweight and dead simple for you to customise.

The M the V and the C

I dont know whys its MVC, it seems more locigal to call it CMV, maybe that was already taken, anyway, heres what all the bits do...

C = Controller

The controller is like a manager, it doesn't do much work itself, but it makes all the important decisions, and knows who needs to do what in order to get the job done.

M = Model

Models are generally where all the real work happens, they are given their orders by the controller and are responsible for fetching and processing the data before returning it back to the controller.

V = View

Views are pretty simple really, they are just ways of presenting the data which the model returns, such as a template.

Logic Flow

The basic logic flow is surprisingly simple, it's only when you start mixing in other design patters that it can be difficult to get your head around.

We start off by sending the Controller a request to view a page, the Page Controller knows that the page content needs to come from the database, so it asks the Model to go and fetch it. The Model heads off and fetches the data and passes it back to the Controller, it's work is now done. The Controller then takes that content and asks the View to make it look nice, so the View heads off and wraps everything up in HTML and gives it back to the Controller. The Controller see's all is good and shows it to the user.

MVC URL structure

As we want to keep the code duplication to an absolute minimum it makes sense to direct every call through a central page, and have that page decide what classes should be instantiated based on the structure of the URL, this way we dont have to have the overhead of having to create a physical page every time we add some new content. For the sake of simplicity we are only dealing with one controller in this example (the page controller) and will expand it to use further controllers later on.

If you havent already setup your local development environment, now is a good time to do so, it's much better than FTP'ing to a live server every tme you want to see the changes.

Here's the URL we will be using: www.example.com/index.php?action=view&pageId=24

The three important parts of the url are firstly the index.php file, every page on your website (no matter what it looks like) will use this file as its access point, and the logic inside it will decide on how to handle decisions such as which templates to use and updating databases. Dont worry too much about the ugly URL structure for now, we will tidy it up later on.

The second part of the URL to note is ?action=view as this the name of the method we will be calling and is responsible for fetching page content, finally we have pageId=24 which is the argument that gets passed into the view method in order to get us the right content.

Enough theory, lets get stuck into some code.

index.php

<?php
require_once('model_page.php');
require_once('view.php');
require_once('controller_page.php');
 
$page = new controller_page();

$action = ( isset($_GET['action']) ) ? $_GET['action'] : 'view';
$pageId = ( isset($_GET['pageId']) ) ? $_GET['pageId'] : '1';

$method = $action;
$page->$method( $pageId );
?>

We start by including the model, view and controller files (we will look at a nifty way of removing these includes later on). We then create a page controller object and use the $_GET['action'] variable as the name of the method we want to call, and pass it the $_GET['pageId'].

 

controller_page.php

<?php
class controller_page {

	function view( $pageId ){

		$model = new model_page();
		if( $pageData = $model->fetchPage( $pageId ) ){

			$view = new view('pageTemplate.php');
			$html = $view->render($pageData);

			echo $html;

		} else {
			// throw a wobbly
			die('Couldnt load the page, sorry!');
		}

	}

}
?>

This is the page controller, and it is responsible for producing plain old HTML pages.

The controller is pretty simple at the moment with just one method which is responsible to fetch you some HTML. The view() method accepts a single argument $pageId, which relates to the content you want to display.
The first thing we do inside the view() method is instantiate the model and try to call its fetchPage() method passing it the $pageId as an argument, if succesful, the model will respond by returning an array of data, which is then loaded into the view, if it fails we show an error message. Next up we instantiate the view class and pass it's render function the filename of the main page template, and the array of data we got back from the model. The view will combine the two into a finished string of HTML and return it back to the controller, so all that needs to be done is to echo it out to the user.

 

model_page.php

<?php
class model_page {

	function fetchPage( $pageId ){

		if( !is_numeric($pageId) ){
			return FALSE;
		}

		if( $pageId = '1' ){
			// pretend we got this data from the database
			return array(
					'title' => 'My first MVC page',
					'keywords' => 'MVC, page, dog, fox, ',
					'description' => 'A simple MVC page' ,
					'content' => '<p>The quick brown fox jumped over the lazy dog.</p>',
				);
		} else {
			return FALSE;
		}

	}

}
?>

First off the model needs to validate the argument which we passed it, as this has come straight from the URL and could potentially be nasty. Validation is best suited to being in the model as models tend to get re-used more than controllers throuought an application and this cuts down on code duplication. This is not to say controllers or views can't validate, just that it's better suited to being in the model. Skinny Controller, Fat Model.

Based on the $pageId the model returns an array of data, or false if the pageId could not be found, this way the controller can decide what to do next.
For the sake of simplicity the data is hard coded into the model at the moment, but you will probably want to get it from the database.

 

view.php

<?php
class view {

	private $template;

	function __construct($viewFile) {

		$this->template = $viewFile;

	}

	public function render( $data ) {

		ob_start();

		extract( $data );

		require( $this->template );

		$buffer = ob_get_contents();
		ob_end_clean();
		return $buffer;

	}

}
?>

The view file is essentially a very simple templating class, you pass its render() method the filename of a template and, an array of data, it will then extract the array of data into seperate variables using the array keys as variable names. once this is done, the tempalte is included, causing any vaiables in the template to be populated with the content we just extracted, all of this content is captured by the output buffer and stored in a string which is sent back to the controller.

You can of course change the templating system as you see fit, a lot of people like to use Smarty, but it's always seemed overkill to me, I like to KISS.

 

pageTemplate.php

<html>
	<head>
		<title><?php echo $title; ?></title>
		<meta name="keywords" content="<?php echo $keywords; ?>">
		<meta name="description" content="<?php echo $description; ?>">
		<style type="text/css">
			body {background-color:#eee;color:#000;font:15px/19px arial,sans-serif;margin:30px;}
			#page {background-color:#fff;padding:10px 20px;border-radius:10px;}
		</style>
	</head>
	<body>
		<div id="page"><?php echo $content; ?></div>
	</body>
</html>

Speaks for itself really, it's just a page of HTML, with a few PHP variables scattered around it..

 

That's it for this part, keep tuned for the next installment, where we will cover bootstrapping, front controllers, and autoloading.

 

Download the Code

Click here to start the downloadFile Name: KP-Really-Simple-MCV-vCurrent.zip
Version: 1.0 (19/11/2012)
File Size: 1.9kb
Contains: KP-Really-Simple-MCV example files

 

By Karl Payne

Comments

There are no comments, don't be shy, somebody has to be first.

Leave a comment