With websites becoming more and more dynamic and interactive, developers often look to frameworks to help build websites and web apps rapidly. While there are a number of great frameworks available, a custom framework gives you the ability to easily customize the framework as you need, and to build with it even quicker - as you would already know the ins and outs of it before working with it. In this series of tutorials, we are going to build our very own PHP5 Development Framework! Let's start with planning our framework and put the basic structure into place.
*Note - Running the demo should display "PCA Framework version 0.1 the HTML output" - which demonstrates the first stage of our framework.
Step 1: This Series
In this series, we will create our own PHP5 Framework from scratch. The Framework will include basic content management features, and we will use it to build a web-based directory for a small organization.
Hopefully, as we go along, you will improve, build up and optimize this framework to suite your needs better, however in these tutorials we are aiming to get a simple framework up and running and powering a website.
Over the next few weeks, during these tutorials we will cover:
- Creating authentication handler, database abstraction layer and template manager
- Bringing these objects together
- Using the framework to manage content, and power our site
- Creating a fantastic front end design.
- Designing for the login process by storyboarding
- How the Framework can be extended and expanded
Step 2: Design Patterns and their use within our Framework
When creating any large computer-based system, be it a desktop application, a distributed network system, or a web application there will always be architectural challenges associated with its implementation.
Design patterns address some of these common problems, and we will make use of a number of design patterns as we create our Framework, to ensure that we have a quality, flexible, robust and usable framework, fit for any purpose! In particular, in this tutorial we are going to look at the Singleton pattern and the Registry pattern.
Step 3: Files and Folders
The first thing to get started creating our Framework, is to create a suitable file structure, such that everything has its place. As well as the files powering the framework, we also need to make provisions for files relating to the website we are going to create with our framework. Most websites and web applications have:
- Some commonly used functions / objects.
- Business logic.
- A design
This gives us a great starting point, files relating to each of those three categories should be grouped together in their own section. Take a look at the directory structure below, we will then discuss the reasons for the structure.
Note that the .settings folder and the .project file were created by the IDE I use, and don't need to be present in your application
Core functions and objects, such as database access, authentication, template handling, email sending objects, email parsing objects, should be stored within a folder called objects, within the PCARegistry folder. This allows us to separate the logic from the Registry (which we will look at shortly) from the objects stored within the Registry.
Next, we need somewhere to store our business logic which is the files we will create which make use of our framework. We should keep these files in a folder called controllers. Each major function that our website or web application does (e.g. business directory listing, providing and managing content, providing an image gallery, etc) would be a separate controller, stored within its own folder within the controllers folder. We are not going to use these in this tutorial, but it is important to have our directory structure in place, so we know how it will work.
The sites design and templates, should be stored within the skins folder. Since we may want different designs (either so users of the application/website we create with our framework can chose from a number of designs, or to change the design depending on season or special event), each skin will be contained within its own folder.
Step 4: The Registry
At the heart of our framework we will have the core functions, such as database access, user authentication, etc. By implementing the Registry design pattern, we can keep these objects stored centrally, within the Registry, making it easy for our Framework and any applications which utilize our framework to access.
The registry design pattern stores and retrieves references to objects, and works in a similar way to a telephone directory: storing and retrieving contacts. We will use it to store these core objects, system-wide settings, and later, any other data or information which needs to be shared across the system.
Because we are storing this information centrally, we only ever want one instance of this registry object to be available within our framework, if more than one were available, then we would have problems where we were expecting a certain piece of data, or a certain object to be in the registry, when it was in fact stored within another instance of the Registry object. To solve this problem, our Registry object will also implement the Singleton design pattern, which prevents more than a single instance of the object being available.
Below is the PHP code for the registry.class.php file, we will look into how it works shortly.
<?php
/**
* The PCARegistry object
* Implements the Registry and Singleton design patterns
*
* @version 0.1
* @author Michael Peacock
*/
class PCARegistry {
/**
* Our array of objects
* @access private
*/
private static $objects = array();
/**
* Our array of settings
* @access private
*/
private static $settings = array();
/**
* The frameworks human readable name
* @access private
*/
private static $frameworkName = 'PCA Framework version 0.1';
/**
* The instance of the registry
* @access private
*/
private static $instance;
/**
* Private constructor to prevent it being created directly
* @access private
*/
private function __construct()
{
}
/**
* singleton method used to access the object
* @access public
* @return
*/
public static function singleton()
{
if( !isset( self::$instance ) )
{
$obj = __CLASS__;
self::$instance = new $obj;
}
return self::$instance;
}
/**
* prevent cloning of the object: issues an E_USER_ERROR if this is attempted
*/
public function __clone()
{
trigger_error( 'Cloning the registry is not permitted', E_USER_ERROR );
}
/**
* Stores an object in the registry
* @param String $object the name of the object
* @param String $key the key for the array
* @return void
*/
public function storeObject( $object, $key )
{
require_once('objects/' . $object . '.class.php');
self::$objects[ $key ] = new $object( self::$instance );
}
/**
* Gets an object from the registry
* @param String $key the array key
* @return object
*/
public function getObject( $key )
{
if( is_object ( self::$objects[ $key ] ) )
{
return self::$objects[ $key ];
}
}
/**
* Stores settings in the registry
* @param String $data
* @param String $key the key for the array
* @return void
*/
public function storeSetting( $data, $key )
{
self::$settings[ $key ] = $data;
}
/**
* Gets a setting from the registry
* @param String $key the key in the array
* @return void
*/
public function getSetting( $key )
{
return self::$settings[ $key ];
}
/**
* Gets the frameworks name
* @return String
*/
public function getFrameworkName()
{
return self::$frameworkName;
}
}
?>
So, how does the Registry object work, and how does it keep our objects stored nicely?
- Objects are stored within an array.
- When a new object is stored within the Registry, the class file is included, the object is instantiated and then it is stored in the array.
- Objects are retrived by passing the objects "key" to the getObject method.
How does it prevent another copy of the Registry object being created?
- The constructor is private, preventing the object from being created directly.
- Cloning the object triggers an error.
- If we need to access the object from within our Framework, and it is not directly available to the file we are working in, we can call the static method singleton ( PCARegistry::singleton() ) to get the instance of the Registry.
Step 5: index.php
With the structure in place ready for the core functionality which we will add in a further tutorial, let's look at how we will access the Registry, and start work on our Frameworks single point of access, our index.php file.
Friendly URLs are commonly available in all forms of dynamic websites and web applications, and one of the simplest ways to do this (and to manage the control of information through our Framework) is to ensure all of our page requests go through the index.php file. In a later tutorial, we will create a .htaccess file to redirect requests from a nice, friendly format, into a format that our index.php file can understand.
The index.php file's code is below. It doesn't do a lot at the moment, but it allows us to get things in place.
<?php
/**
* PCAFramework
* Framework loader - acts as a single point of access to the Framework
*
* @version 0.1
* @author Michael Peacock
*/
// first and foremost, start our sessions
session_start();
// setup some definitions
// The applications root path, so we can easily get this path from files located in other folders
define( "APP_PATH", dirname( __FILE__ ) ."/" );
// We will use this to ensure scripts are not called from outside of the framework
define( "PCAFW", true );
/**
* Magic autoload function
* used to include the appropriate -controller- files when they are needed
* @param String the name of the class
*/
function __autoload( $class_name )
{
require_once('controllers/' . $class_name . '/' . $class_name . '.php' );
}
// require our registry
require_once('PCARegistry/pcaregistry.class.php');
$registry = PCARegistry::singleton();
// print out the frameworks name - just to check everything is working
print $registry->getFrameworkName();
exit();
?>
So…what does our index.php file do at the moment? It:
- Calls start_session right away, to ensure we can use sessions throughout the Framework (this must be called before any output.
- It creates a definition of the current file path, so we can reference the frameworks root directory from elsewhere, and it creates a definition that we will use to ensure all of the Frameworks files are being called from the Framework itself, and that someone isn't trying to call one of the files directly
- It uses the autoload function to determine where any classes may be located. In this case, it points to the controllers directory, as this is where our business logic will be stored.
- It includes the registry class (this is needed as the class is not within the controllers folder where the autoload function would find it, and references the instance of the Registry to the variable $registry.
- Finally, it prints out the name of the framework, to demonstrate a simple function from within the Registry.
We can see in more detail how the Registry will work within our Framework - by creating some dummy class files for it to use. With a template class in a new template.class.php file in the PCARegsitry/objects folder, we can demonstrate this, by adding some additional code to our index.php file.
On the line after we first reference $registry, we could add:
$registry->storeObject('template','template');
If our template class had a method contained within it, such as generateOutput, we could call this method from index.php like so:
$registry->getObject('template')->generateOutput();
Our Framework now has a basic structure to it, and we have a Registry in place for our core functionality, in the next tutorial, we will look at creating the objects which our Registry will store, starting with a basic database abstraction layer and a security manager.
Related Posts
Check out some more great tutorials and articles that you might like
Plus Members
Source Files, Bonus Tutorials and
More for $9 a month for all TUTS+
sites in one subscription.












User Comments
( ADD YOURS )Lachy Groom August 25th
Wow! Awesome
Can’t wait for the next part, cheers.
( )Niklas August 25th
This will be a great series! Very interesting indeed!
( )ChaZ August 25th
Damn, I want the next part already!
( )Awesome so far!
(please delete my previous comments)
Shane August 25th
I understand the personal satisfaction of creating a PHP framework, but I cannot see how the advantages of a mature, well tested, feature-rich framework such as CakePHP or CodeIgniter don’t form the natural choice for most developers who want to get on and create things without going back to ’square one’.
Having said all that, creating a framework, and taking nettuts readers through its development is a useful aid to understanding an implementing PHP, so thanks for posting
( )Al August 25th
I hope you won’t be serialising any objects, as you call session_start before you load any class definitions in. Then again, with autoloading classes, you can’t really guarantee you’ll load all classes in before calling session_start.
Also, is there any reason you’ve used a singleton for the registry? All your data is stored statically, so you COULD just have all static functions and no instances of the class. When I make a singleton class I tend to have two static parts: the singleton object and the singleton method call. Everything else is an object method/variable. Just seems a bit silly to store data statically, and use a singleton instantiation to access public methods of an object that just uses the statically-stored data. Maybe you have a reason for it, and I’d love to know, but I can’t think for the life of me why you’ve done it.
( )Maicon August 25th
I hope the sequence come soon =)
( )Dan August 25th
This. will. be. awesome.
( )ThinkSoJoE August 25th
Thanks for this – I’ve been working on creating my own CMS but I never really learned about functions and things of that nature, so this series will be absolutely helpful!
( )JPH August 25th
Great series – can’t wait to see the rest.
( )Jay Salvat August 25th
Glad to see some more mature tuts.
It looks very interesting. Can wait to the next chapter.
Even if dozens of frameworks are existing yet, it’s an ideal topic of tuturial. It’s good for webdevelopers to think about the ‘behind the scene’ of creating such a framework.
( )Rijalul Fikri August 25th
Waiting for the next serial
( )Ben Griffiths August 25th
This is great – I’m currently building a framework, so this should help me out loads
( )Ben Griffiths August 25th
By the way, will you be covering routing? I have done this, but I’m sure there’s a better way than what I’ve done
( )ashvin August 25th
Now That’s What We Call Tutorial!
( )Miles Johnson August 25th
This is not a framework… its a basic template engine, and a basic one at that. Singletons should not be used for templates either because you do not want to keep templates in memory in case you wish to use the same variable name in another location.
If you want a simple framework => CodeIgniter
( )o.O August 25th
WOW!
( )Some months ago I started to code a framework but I don’t like it any more…
Your framework tutorial is really good!
*thumbs up*
Philo August 25th
Nice Tutorial!
( )James August 25th
This was good to read through… It’ll be interesting seeing how the series unfolds!
( )dronix August 25th
come one peeps, you guys are missing the point of this series. Its not about which framework is better or not, its about learning php. However, a series on how to use on of the most popular php framwork (cakephp or codeigniter) would be nice too. Keep this series coming, waiting for part 2!
( )Michael August 25th
Thanks for the comments so far.
@Miles Jonson – it isn’t a template engine…we have not even touched the templates side of things, this is just the basic structure to the framework. The registry is to hold things like the database access, template handler, authentication management, all these core classes.
@Ben Griffiths – I have not quite decided how to tackle the routing aspect.
@Al – there was a reason for using singleton for the registry, but as I was working on it I don’t think the reason applies anymore – I’ll have a look at my notes when I’m back in the office and see what the reason was.
( )David August 25th
@Miles Johnson – as dronix says, it’s about learning php more than building a framework, and future tuts look like theyll cover more detaild things.
( )David August 25th
@Shane – the advantages might be for larger clients who insist on everything in their systembeing proprietary, so you can’t use Cake etc
( )Connor August 25th
Wow…definitely an original tutorial! Nice
( )Braden Keith August 25th
AHHHH THAT’S HOW IT HAPPENS. This is good stuff, keep dishing it out, I hope we will go beyond that list above
( )Thomas Milburn August 25th
Brilliant! A tutorial I’ve been looking for. I’ve been messing about with PHP5 recently to make my own framework but I’ve had several problems to solve. One of which is how to let my models have access to several main objects. The registry idea is a good solution.
I’m definitely looking forward to the next part. Thanks Michael
Could you explain what PCA means?
( )Vince August 25th
Nice to see a tut like this. Hand-rolled my own PHP framework out awhile ago, great way to learn.
( )oisean August 25th
This should be an interesting tutorial series.
Have any of you ever used the Qcodo framework?
( )Abethebabe August 25th
Finally a PHP specific tutorial, really looking forward to this series!
( )Michael August 25th
@Thomas Milburn its the acronym of my businesses name “Peacock, Carter & Associates” => PCA :p
What would you guys prefer for the next tutorial? I was thinking about covering the database layer and the template handler.
( )daok August 25th
“Next, we need somewhere to store our business logic which is the files we will create which make use of our framework. We should keep these files in a folder called controllers.”
Euhh I think it has a problem there… business logic and controller need to splitted… go see MVC pattern… Model in real MVC is not in the Controller.
( )m|ke st3phenson August 25th
Awesome~article! keep it coming…
( )Dave August 25th
Great tut.
One question, in the interest of making this more flexible would you not use a class to manage the session element? This would give it the ability to have custom sessions such as DB based.
Looking forward to the next part.
( )emilio August 25th
fantastic! I’m wainting for the second part
( )insic August 25th
wow! this is what i am looking for. i have my own design php framework though. but i am exited and must follow this series.
Please keep it up.
( )Daniel August 25th
very interesting tutorial! just what i am looking for
( )Michael August 26th
@daok The way I generally do it (which is just my method, it may not be the best) is that the database essentially acts as the model, it certainly isnt a strict MVC design – just something losley based on some of its ideas. So for example, we have a page of content stored in the database, we have the view which is the skin files, and the controller which interperates the users action (clicking a link) to generate the page. This is a method (for web based applications) which I’ve discussed with an expert in design patterns, who seemed to think it was a reasonable way to do it.
I find this method works well for me, even though it may not be the best; this series is also about laying the groundwork – I’m hoping anyone following this tutorial to make a framework will make their own unique framework based on my ideas, their needs and their own ideas.
Oddly enough, the progress I’ve made over the past few weeks on this Framework (as I’m rewriting my old clunky PHP4 framework while I do these tutorials) provides me with some ways to create some basic models which could be used – I’ll see how things go with it, and I may bring them into these tuts, to make it a little bit more MVC based. Thanks for your comment!
( )Gilbert August 26th
Looks like a cool set of tutorials. Looking forward to the next ones.
( )Christoph Herrmann August 26th
Hi,
you don’t use no really the options of PHP 5 in my eyes in this first class and the first file. Examples for my Opinion:
1) In the method “singleton()” you should better use reflection, instead of
# $obj = __CLASS__;
# self::$instance = new $obj;
you should use (not tested):
$reflection = new ReflectionClass(__CLASS__);
self::$instance = $reflection->newInstance();
or better and faster:
self::$instance = new PCARegistry();
2) You use the function “__autoload()” that is outdated, you should better use “spl_autoload_register()”. With the second method you have the alternativ to define more than 1 functions/methods to load inexistent classes/interfaces.
I hope I can help you with these comments. And execuse me if my english is not the best.
( )Adam August 26th
@Shane, there’s a larger percentage of people that use a custom framework than pre-existing ones like codeignighter, cakephp etc. So in that case, this comes in very handy.
( )Kevin August 26th
Looking forward to the rest of this series. Eactly what I need at this point. Cheers!
( )Jonathan August 26th
Is this similar to Zend Framework?
( )Bendikt Myklebust August 26th
you can actually have most of the content of the index file in an “conf” file.. just to separate code. =)
( )Michael Peacock August 26th
@Christoph Herrmann thank you very much for your comment, there are probably quite a few better ways to do certain things. I’ll have to look into the ReflectionClass, I have not really looked at Reflection in much detail, nor have I looked at spl_autoload_register() before.
As I’ve said before, I hope that those of you who find this useful use it more as a baseline for your own framework, and build upon and improve it as we go along.
( )EmEhRKay August 26th
Interesting. Is there any particular reason why you are not using the PEAR naming conventions?
( )Christoph Herrmann August 26th
Hi,
since 2 years I write a framework too. if you are interested in contact with me, write me an email (herrmann@dragonprojects.de). I would be interest in the process of the development and perhaps I can help you a little bit.
again any notes for your first class:
( )- instead of trigger an error at cloning the singletonclass, you can give the singleton instance back. if you really forbid the cloning, throw an exception instead the trigger error, so the developer can catch the exception and forward the user to an errorpage
- you don’t must make all attributes static. Only the singleton object must be static, the another attributes can be normal, because it exist only one object of you class
Wilhelm Murdoch August 26th
Interesting article. I’ve been working with PHP for close to 10 years now and actually wrote my own object registry a few years back that I still use to this day. It’s a great way to store frequently used core objects. Just throw them in a bucket and then pass said bucket by reference through to your controllers.
I’m sure this series will benefit a lot of the beginners!
( )Joey M. August 26th
You literally have me on the edge of my seat for the next installment of this tutorial. I hadn’t even thought about creating a framework till now! I’m going to start doing something like this right away, but I am curious how to implement my database and authentication classes. When can we the next chapter?
( )Santiago Carmo August 27th
I not need speak more nothing, the guys have already spoke all, now I waiting the next part of the article.
( )Peter G. August 27th
same as @Joey M
( )Reid August 28th
This series is going to be a very successful one for this site! Can’t wait for the next part!
( )Robin August 29th
This is really a great post. I can’t wait to see where it goes. I’m also happy to work along with this tutorial since it is one of the few I’ve seen sans anything WordPress. A CMS from scratch. A great idea.
( )Thanks.
Evodesign August 29th
When comes the 2nd part?
=D
( )Sascha August 30th
WOW! Can’t wait for part 2
( )Maako August 31st
Okey – now this is some advance tutorial what I’ve been looking for for awhile!
Can’t wait more! Thanks…
( )ThinkSoJoE September 1st
So, any word on when the next part is going to be? I’ve been looking forward to it since this part came out!
( )Michael Peacock September 1st
Soon
I’m working on it!
( )ThinkSoJoE September 1st
wow – wasn’t expecting an answer so quickly! Thanks!
( )Ach September 1st
Really really great work. Anxiously awaiting the next batch.
( )John September 2nd
Come on, the suspense is killing me! When’s the next part out??
( )insic September 3rd
i cant wait the next part. part II please
( )spoontacks September 3rd
What IDE are you using in this tutorial? Or at least, what is a good IDE to use for PHP?
(Anyone else who would like to answer, please feel free to do so.)
( )enrizuu September 3rd
This is very interesting….
( )Where is the SECOND PART?
insic September 4th
@spoontacks ZEND IDE rocks. But if you want free you can try Aptana, NetBeans just down load the php plugin. Enjoy…
( )Sajhu September 4th
Great! thanks, waiting for te next part!
( )EllisGL September 5th
Very nice – but a couple of things could be optimized and more secured.
I’ll talk about the later. Securing the session:
session_start();
/**
( )* Secure the session – Basic
*/
if(isset($_SESSION['HTTP_USER_AGENT']))
{
if($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT']))
{
session_regenerate_id();
$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
}
}
else
{
$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
}
Robin Card September 5th
Hi Nice tutorial but one amendment.
# The constructor is private, preventing the object from being created directly.
# Cloning the object triggers an error.
Why not just declare the class as an abstract?
# abstract class PCARegistry {
( )hdragomir September 7th
You hear so much about the MVC design pattern, yet there’s so little information on how to actually implement it. This tutorial is a great stating point for many young developers.
( )Great job!
Adrian September 11th
Eagerly waiting for the second part!
( )Anuj Seth September 16th
Wonderful tutorial. I just completed reading Part 1 & 2.
Just wondering though…why reinvent the wheel? What is the drawback of using frameworks like CodeIgnitor or CakePHP?
( )Aditya September 17th
YOU ARE A ROCKSTAR, Mike!!! Awesome tut, I can’t thank you enough! And also many thanks to Nettuts, who not only brought up this framework of awesomeness to provide these type of tuts, but also refrained from keeping this series in the premium category.
For those who are whining about re-inventing the wheel, I have this to say: stuff like Registry and Singleton models are not talked about in the normal tuts as they are too advanced, and doing this type of work helps those of us who are not fortunate enough to be computer engineers the more intricate details of programming.
And, I wanted to say this for a long time now: Insic, you are gorgeous
( )Carlos Fernando Benitez September 23rd
hello, thank you for sharing this information.
Michael, would enable a tutorial on how to make a CMS
Sincerely, carlos
( )Rasmus September 24th
Awesome tutorial – love it. But a link in the bottom to part two wouldn’t be that bad.
How ’bout a few on JavaScript from scratch? Not everybody is so keen on learning javascript the jquery way.
( )David September 28th
Thanks for the tutorials.
Excuse me, as I’m probably over-looking how to properly use the singleton method, but I have a menu class for generating a side-menu and it complains as it can’t get access to $registry?
class menu {
function execute() {
$query = $registry->getObject(’query’);
$this->categories = $query->getAll(’admincategories’);
}
}
I’ve done a store object for query, loaded by a storeCoreObjects function in the registry class, and I understand why menu can’t access it, as singleton is ran outside of the class, but what’s the best way for menu class to access the query class so I can run getAll?
( )bigwetbutt September 29th
Where’s PART 2? I’m starting to think it’s not coming. I might check back 1 more time…
( )Paul October 18th
In the storeObject function, what is the use of the self::instance in the brackets when creating an object?
“self::$objects[ $key ] = new $object( self::$instance );
I couldn’t work out it’s use, so I removed it and everything still works fine!
( )Ben October 24th
Tired of writing lines of lines with source code each time you are coding a website? Feel like just copying and pasting but afraid that you might end up getting sued?
No more worries, WebCodeBase is the website you’ve been looking for!
Here you can find source code that you can copy without any issues at all, we guarantee that you will not get sued for using the code we put on this website. So what are you waiting for?
http://www.webcodebase.com
( )Ales November 2nd
I was a long time looking for something like this. The article brings a complex wiew on the topic.
( )Michael November 28th
Definitions and includes IMHO would be better using like this
( )define( “DS”, DIRECTORY_SEPARATOR);
define( “APP_PATH”, dirname( __FILE__ ) .DS );
require_once(APP_PATH.’PCARegistry’.DS.’pcaregistry.class.php’);
Those people who using Windows
Dave December 11th
Is there any way to store an object in this registry class with params in counstructor ?
( )Anton Agestam March 2nd
Great tutorial!
( )Angel March 14th
Thank you
( )J April 6th
Thank you sir for this tutorial!!
( )You are the man.
alex April 20th
Do you think you should use the __autoload() magic function instead of this?
require_once(’objects/’ . $object . ‘.class.php’);
( )alex April 20th
Oh whoops, you are, somewhere. That’ll teach me for not reading the whole thing first!
( )CgBaran Tuts May 5th
Great advanced tutorial thanks
( )Jesse July 30th
Thanks man!
( )chknkiller August 22nd
Nice tutorial indeed. But I have a question. Could you tell me which is the editor shown in the picture?
( )