Monday, September 26, 2011

Implementing Singleton Design Pattern with PHP 5 (only-one persistent object in Session, MVC approach, etc.)

(Draft version, It could be improved or modified)


Introduction

In this article I'll explain you how to implement an application based on Singleton design pattern by using object oriented PHP 5.x.

Before starting, You must know some concepts for understanding the whole article.

Please, read the paragraph below before continue.


Requirements


You need to know:

1) The concepts about "static" methods and properties of a Php Class

2) What is a MVC (Model / View / Controller ) paradigma and how it works

3) What are "sessions" in Php and how they works

4) Obviously you need to know the "Design Patterns" concepts and in particular what is a "Singleton"


Let's start

Before starting, I think that is important to specify that every time you call a PHP script, all the variables, handlers, etc. will "born" when the script is called (request) and they will be "destroyed" when the script ends.
Indeed for the Php engine, every script is considered a stand alone "entity" althought it is part of an application (Shared Nothing Architecture); each script must be considered "unlinked" from the status of the other scripts(... and itself if you call it one more time...);
This means that every time you need to process something in different scripts (e.g. database, files, variables, objects, etc.) you need to re-open a connection to a databases, re-instantiate and object, etc.
If you need to pass internal information between scripts (eg. a value, a correct users authentication, permissions, etc.) you need to use "sessions".
By using "session", you can store values (or sometimes entire objects) and passing them between scripts; by using this method you can "simulate" a persistence of data in your "application" and a "connection" between scripts(in a similar way of Java).

Note that:

1) Php resources (like db connection or files handlers) cannot be stored into session, so you need to reopen them in EVERY script.
2) The session allows the developer to store information for each single user, so information cannot be "shared" between users



Some notes about the implementation of the singleton design pattern with PHP

What I wrote previously is very important according to the "Singleton" concepts (when applied to Php).
Singleton-model based class indeed requires that its "status" must "survive" in the whole application and not on a single script, so the only way to satisfy this concept is the use of Php Sessions.
Another important thing, because Sessions cannot be shared between users the application cannot have a single istance of a Singleton class, but a the developer had to create an "indipendent" singleton class for each user.



A pratical example of Singleton design pattern

When you read about Singleton on blogs, books, magazine you'll find that it is usually used for storing the "status" of the actions made by one or more users into an "application". In other words they talks about "logging".

The code that you'll find in this page, will show you how to keep track of clicks on one or more php pages by using a only one object (which implements singleton) that will be "passed" between scripts.
As required by the singleton design pattern, only one object will we created by using PHP static members and properties. Before the end of the excecution of a script, the object is serialized and stored in session so it'll survive to the "garbage collector" of the Php engine.



The Code

In the example, I use a separation between business logic and view (html pages) so it's more easily to describe code and make the things "clean".
If you don't know this coding approach on Php, I suggest you to take a look to Model/View/Controller (MVC) concepts by googling around.

Anyway, files involved into the example are:

header.html - This file will be included in view scripts for generating a valid "header" for xhtml document  (page1.php, page2.php, clear.php, print.php)


footer.html - This file will be included in view scripts for generating a valid "footer" for xhtml document  (page1.php, page2.php, clear.php, print.php). It also displays a set of links for calling every page of the "application".

controller.php - This file is the "controller" for the MVC model, it receives the parameter "func" by GET method and selects the correct action. When no parameter are passed, it'll will call the print.php script that shows the content of the "log" stored into the singleton object

singleton.class.php - The implementation of a very simple class based on the Singleton design pattern.

page1.php - When you click on the link for page1 (showed by footer.html), the controller.php will be called, it will store on the log (by using singleton object) a "track" of the page calling than it will show page1.php. This page represents one of the "view" side of the application.

page2.php - Same as page1.php

clear.php - It'll clear all the log entries

print.php - When you click on the link for page1 (showed by footer.html), the controller.php will be called, than the content of the log will be showed on the browser (taken from Singleton object)

The aim of the whole application is to show how the singleton object will be inherit one time only and, because it's stored on session, it'll survive to garbage collecting of the Php Engine. Indeed it's status (log lines) is not lost.
For details about how every file works, see comments inside code.

Note: All the code inside is released under GNU/GPL license version 2.1


The singleton class (singleton.class.php)




The controller (controller.php)




The Page1 view (page1.php)




The Page2 view (page2.php)




The Print log view (print.php)




The log reset view (clear.php)




The "header" and "footer" template files


Filename: header.html

 


Filename: footer.html






Some "Screenshots"


Example1 - controller.php called without parameters

Actions logged

Line 0: Logging start at: logged at 2011-09-26 16:09:54


Main page | Page 1 | Page 2 | Clear Log 




Example2 - controller.php called with parameter func=1

(The page1 is "visited", so a line in the log is stored)





PAGE1 LOGGED

Main page | Page 1 | Page 2 | Clear Log 







Example3 - controller.php called without parameters but the with 1 event in the log



Actions logged


Line 0: Logging start at: logged at 2011-09-26 16:09:54
Line 1: PAGE1 logged at 2011-09-26 16:09:18


Main page | Page 1 | Page 2 | Clear Log 





Notes



I hope my code will help you! Let me know! ;)



See you, sincerely

Angelo Fonzeca