Create a PHP Framework

Creating a PHP5 Framework – Part 1

Tutorial Details
  • Difficulty: Advanced
  • Completion Time: 1 Hour

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.

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • PhantomCode

    I was just wonder why you format your block comments with the extra asterisk, like this:
    /**
    * Comment
    */
    rather than this:
    /*
    * Comment
    */

    Is it just because you think that looks better?

    • Markus

      IDE’s like Aptana or Zend Studio recognize those Comments and display them at tooltips when u use one of the functions on another place.

    • Scomp

      Have you heard about PHPDoc syntax? Not? You should read about it, then you’ll understand, what the difference is between /** and /* commenting style.

  • Pingback: El Blogig » Nou framework MVC en php5.

  • Markus

    Why do you prevent cloning of the object in the registry?

  • http://suckincrazy@hotmail.com Ivan

    Tu aporte esta realmente interesante!!
    Me gustaría que siguieran enseñando más acerca de este tema.

    Gracias!

  • http://www.webtasarimsitesi.com ertan

    very interesting idea, I will follow and read other parts.

    thank you

  • Thomas

    Is PART 2 finished? please.. ^^

  • Scomp
  • http://kodegeek.wordpress.com Musa

    Thanks for your nice tutorial. I am following this tutorial, just one thing to ask on this part –
    why did you pass the registry class instance on storeObject method as parameter while you create and store other class objects to registry? i didn’t understand that – would you explain please.

    Thanks

  • http://www.danielribeirogomes.com.br Daniel Ribeiro Gomes

    Great tutorial! Keep it coming!

  • http://www.gunduzmetal.com Hurda

    thanks you

  • Pingback: MVC Post Collection « MYSTERY ZILLION Education

  • http://www.dehacopkonteyner.com çöp konteyner

    I always follow your site thank you wish you continued success.
    Thank you.

  • Pingback: Help comprehending how the following framework fits together: | DeveloperQuestion.com

  • Ben

    The world does not need *another* php framework!

  • foo

    I know this isn’t helpful but what is it with php developers and this constant need to write their own frameworks or CMSs the whole time?

    I see the merit for learning reasons but please, there are so many frameworks out there that are going to be better and better supported than anything you will ever write. If you need to explore this stuff, get to know how some standard frameworks work.

    • Ben

      And time would be so much better spent learning to build add-ons and plugins for the top framework..

      contribute to the existing code base, don’t write frameworks..

    • bar

      no foo,.. this is useful for anyone who want to learn about framework.. this tutorial make it simple.. for newbie like me this is very usefull.. thanks alot

      • http://www.firmawebdesign.net costicanu

        Agree with you. Very very useful this tutorial!

    • mronyx

      “that are going to be better and better supported than anything you will ever write”

      if bill gates obeyed you in this matter years ago, there would be maybe no usefull software to use. and if everybody behaved in same way.

      yes we all will listen to what you and such tell as to do. we restrict our ideas to your commands.

      are you paying me to order me what to do?

    • Mike

      I agree with you to some degree..
      There are a lot of frameworks already readily available. BUT, saying that no more should be created and that if someone creates one that it will never be supported by others is horrifically inaccurate. There’s a lot of frameworks but I still find frameworks that have bits and pieces of what I want and what I don’t want. Codeigniter for example GREAT documentation, no scaffolding. Yii framework, GREAT scaffolding and absolutely crap documentation and reference material. Now if anyone ever were to create a framework that had what everyone wanted then yes there would be no need for a new framework but that will never happen. We will always find frameworks that somewhat work for us but still be lacking bits and pieces of what we need. So I say until that framework is created let 1000 monkey’s create 1000 frameworks for 1000 years and see what we get.

      • Elijah

        Why don’t you spend time learning and documented a framework that has that poor documentation, or writing a scaffolding terminal app for one without it, rather than reinventing the wheel?

        I mean don’t get me wrong I don’t mind this post I’m sure it’ll help a lot of people, but this approach is well documented and known in programming.

        Lastly, I agree there is no reason you shouldn’t write your own, perse, but the PHP community is what I’d like to call ‘framework rape’, there is just too many, everyone wants their own there are tons that are nearly identical, and most follow a really bad pattern of ‘doing it for the developer’ I’d rather adapt a pythonic model. The framework should handle very few things for you, and dependencies should handle the rest, vendor or your own libs should be extend the framework and be used in your application, not be part of the framework.

        In that regard every framework is wrong except maybe SlimPHP, and other sinatra clones.

    • http://www.ianhoar.com Ian

      This is a ridiculous comment. How do you know they are way better than what someone might be writing right now. Some people enjoy pushing their limits, and yes most of them will not create the next big framework or CMS, but if everyone had your mentality there would be no Drupal, WordPress, CakePHP, Codeigniter and the load of other incredible software we have today. I also guarantee you that these are not the last Frameworks and CMS’s we will see. Eventually someone who doesn’t subscribe to your mantra will create something that is even better than these.

      There is also something to be said to using your own framework for your projects.

    • adam

      If you are just interested in getting a dynamic site up and running, then I see your point. BUT many of us are actually interested in learning about the language. Learning a PHP framework (esp. when starting out with PHP) obfuscates the actual language because now you are not learning PHP, you are learning the framework. If you don’t start out with a good base knowledge of PHP, then it makes it harder to understand other people’s code written with a different framework (or no framework at all).

      • Ian

        I have to disagree. I have been learning the language until I’m sick of it. There’s tons of info on the language it’s self but not enough info on how to properly put it all together in a well designed framework and asside from the CI from scratch tut here, there’s not nearly enough information on frameworks.

        Just in this first part I just had a aha moment about frameworks and that is why I’m going through this tutorial.

        So a big thank you from me for this.

        Though I wish people wouldn’t start series for frameworks like zend and fuel and then just drop off the planet after part two or three because those would be great too.

    • Yehonatan

      Then what is the point of programming? You’re just like a monkey that copy others instead of learning and doing by yourself.

  • bar

    It would be helpful if only those who thinks this article is useful would comment and it would indeed be productive, otherwise go and blog about your whine somewhere else. There are people who ‘needs’ this for ‘their’ own purpose and your whine is obviously biased towards your preferences. I like this article so without further fueling an insensible discussion with a poster who seem to love dictating the needs of others by narrowing the worlds of others to their own ideals and perspectives…

  • Pingback: Create a Basic Shoutbox with PHP and SQL « Itzurkarthi's Weblog

  • http://www.crlog.info Courtney

    Bit old of an article but I think some commenters are missing the point of this tutorial or at least one of them. Its not to reinvent the wheel and build a framework from scratch but if no one knew how to build frameworks in the first place, create ones such as Cake and Code ignite wouldn’t exist…who would build them?

    Its a learning thing, someone needs to know how to write the tools while some others just simple need to know how to use it. A tutorial like this is hardly directed at the latter…

    Its a great tut, i always use codeigniter but there’s no harm in knowing the underlying concepts :-)

  • http://www.paddyvisions.com/ aditya menon

    someday, i will grow up and write my own framework, using this awesome, awesome series of articles.

    till that day, however, it’s always codeigniter for me :D

  • john

    this tutorial is awesome….am writing my own simple framework for my own projects….

  • nik0

    If you wrote part 1 i think you want to write a part 2 , i wait it with impatience!

    Cool i know what is a singleton now :)

  • http://www.xpertsopinions.com shoaib

    nice work folks. i have .net background and now thinking to switch toward open source. nice sharing

  • JG

    Watching how somebody else approaches writing a framework is useful. I have always benefited from looking at PHP frameworks because invariably somebody comes up with a good idea that I can use in my own work.

  • frostymarvelous

    Well, personally I don’t use frameworks since I don’t know how they work.
    I think learning about them will give me a chance to understand them and be able to better utolize them.

    Great tut. Just learnt about the registry pattern. Btw, to the whiners, you don’t expect me to use zend for a simple website do you? Cooking a simple one that I can reuse suits me better than that.

  • Pingback: Built your own MVC PHP framework tutorials - r00t.gr

  • Mauricio

    This tutorial is from 2008, don’t expect to see a part 2 in 2011..

    however, I think that not always it is pratical but making your own framework gives a lot of experience for sure. I’m making my own after some sites with codeigniter and cakephp.

    I would say “stay away from cakephp”, from my experience with it. It boosts a lot your speed in the beginning, but if you’re doing a more complex app, at the end you just spend a LOT of time tweaking and trying to hack cakephp to make it work like you would expect.

    But, it’s just my personal experience with it.

    • Ian

      Ha! I didn’t even realize how old this was but it’s still good learning.

      And Actually there is a part 2 and 3 but they are not named the same. If you use the search and search for “Creating a PHP5″ they are all 3 on the first page of results.

      I’m going through part 2 and 3 and see where it goes.

  • http://cancerblogx.info Ken Dietert

    Good weblog. Plenty of helpful information here. I was looking for this.Thanks for sharing!

  • Pingback: Wokay.com: 12 + Tutorials für die Erstellung von PHP5 MVC Framework | PHP Boutique

  • Pingback: Creating a PHP5 Framework – Part 1 | Web Page Tutorials

  • http://www.njoy.com.tr njoy

    shares, shares enjoyed a very good site

    I love the wonder

  • Pingback: PHP Tutorial Collection: Build Your Own PHP Framework - webgsolutions

  • Jason49R

    Very good Tutorial.

    This gives you insight what goes behind the framework.

    If you develop a framework which you support it is the best support you can get.

    You can add functionality what you need,

    Great.

  • Rao

    mr. Peacock no doubt an exellent work. you have used the design patterns that is just perfect. i am working in magento and your work kinda resemble that , which makes my interest grown in this article even more.
    ok where is the next part of this tutorial?

  • http://www.aneesh.info Aneesh
    • Jeff

      thank you aneesh!

  • http://rishiportfolio.tk M.S.Rishikesh

    Thank you Michael. You helped me in everything!

  • Hyyan

    Will , I Think the whole idea of this article is stolen from “PHP 5 Social Networking” Ebook .
    We are not stupid

    • ian

      lol you mean the book that was written by the author of this article? He stole it from him self.

      Glad to find this though. I’ve actually already written my own small framework and need to add a caching mechanism so should get some useful info here even though it’s 4 years old.

  • http://www.linux7world.com Md.Murad

    This is Good content