Design Patterns for Web Programming in PHP
1. Singleton pattern
Name: Singleton
Problem: You need exactly one global instance of a class and a global point
of access to it.
Context: Any
Solution & Consequences: Make an encapsulated static variable holding
the single instance of a class. Provide a get-method that:
• has a static variable for holding the one and only instance
• instantiates the instance if it does not exist already
• returns the instance.
This method returns the one and only instance of the class. So from
the performance point of view you gain a lot. The singleton pattern
prevents the application for making unnecessary many objects, which
results in a performance gain.
Implementation: There are some problems with implementing the single-
ton pattern in PHP:
• In PHP4 it is not possible to define static variables in a class. But
we definitely need a static variable to store the instance. Happily
we can define static variables in a function.
• PHP did not support static methods but the latest version of
PHP4 you can just call a method like this: class::method(). This
is used in the implementation example.
Now, lets have a look at how an implementation would look like:
//
// This is the class of which you want only one instance
//
class yourClassName {
…
//
// This is your classcontructor
//
function yourClassName() {
…
}
//
// This is your helperfunction for retrieving the instance
//
function &getInstance() {
static $instance;
if (!isSet($instance)) {
$instance = new singleton();
}
return $instance;
}
function someMemberFunction() {
…
}
…
}
The helperfunction getInstance is the global point for accessing your
instance. Within your application you can now use your class like this:
$instance =& yourClassName::getInstance();
$instance->someMeberFunction();
Notice the ampersand (&) used in the assignment of $instance, this sign
is very important because it makes sure you get the object itself and not a
copy of it. Just the same story goes for the ampersand preceding the name
of the member function getInstance() in the declaration of the class.
While looking on the web I found several implementations of the single-
ton pattern for PHP that are not working, because they do not make use
of the ampersand. So be careful with implementing this pattern and make
sure that you test your implementation.
2 Strategy pattern
Name: Strategy
Problem: You need several different stategies that solve the same problem
to be easily interchangeable with each other. For example, a website
with support for multiple languages and currencies.
Context: Any
Solution & Consequences: Solution:
• Create a super class (Strategy) that is used as a shared interface
for the concrete strategy classes.
• Define a subclass (ConcreteStragegy) for each strategy needed,
that overrides the member functions of the super class.
• Create a reference in your PHP application to one of the sub-
classes (the concrete strategy that you need) and use this refer-
ence throughout your program.
The consequence is that in the PHP-application you can freely change
the reference from one subclass to another (from one concrete strategy
to another) because they now have the same interface.
PHP does not support interfaces, so you are not forced to stick to the
interface of the super class. It is your own responsibility to check if
you stick to the interface.
UML diagram:

Implementation: In this example implementation we want to print a list
of names. We want two strategies: one for printing the list lexico-
graphically ascending, and one for printing the list lexicographically
descending.
Here is a sketch of the implementation:
//
// Superclass (the interface class)
//
class printListInterface {
function execute($namelist) {
}
}
//
// The subclass (concrete strategy) for printing the list ascending
//
class printListAscending extends printListInterface {
function execute($namelist) {
// Sort \$namelist in lex. ascending order and
// print the list
…
}
}
//
// The subclass (concrete strategy) for printing the list descending
//
class printListDescending extends printListInterface {
function execute($namelist) {
// Sort $namelist in lex. descending order and
// print the list
…
}
}
Now you can make a reference in you PHP application to the concrete
strategy of your choice:
$printList = new printListAscending();
and use the reference:
$names[0] = ’Ralf’;
$names[1] = ’Paul’;
$names[2] = ’Frank’;
$printList->execute($names);
3 Model View Controller pattern
Name: Model View Controller
Problem: You want to be able to change the appearance(UI) of your web
application from time to time, or you want to offer multiple UIs for
the same application in an easy manner.
Context: Changing or multiple UIs for the same application
Solution & Consequences: Devide your application into 3 parts:
The Model (Procesing): the model is a representation of the data
and the possible operations on it.
The View (Output): the view renders the contents of the model. It
is a view on the model.
The Controller (Input): the controller translates interactions with
the view into actions to be performed by the model.
Implementation: This is a sketch of an implementation of a MVC-pattern
applied to a web shop. In this example the user can look up a product,
or add a product to the system.
The Model Component:
This class is like a database wrapper or database adaptor
class ShoppingModel {
//
// Retrieve the product from the database
//
function getProduct($id) {
…
}
//
// Store a product in the database
//
function addProduct($id, $name, $description, $price) {
…
}
}
The View Component:
The view class is responsible for generating HTML(the view on the model)
class ShoppingView {
var $model;
//
// Class contructor that stores the model
//
function ShoppingView($model) {
$this->$model = $model;
}
//
// Print HTML-header
//
function printHeader {
…
}
//
// Print HTML-footer
//
function printFooter {
…
}
//
// Print HTML-representation of a product
//
function printProduct($id) {
$view->printHeader();
$product = $this->$model->getProduct($id);
// Give the HTML representation of the product item.
// By printing a some HTML tags and properties of the product
…
$view->printFooter();
}
//
// Print HTML-representation of a message
//
function printMessage($message) {
$this->printHeader();
print($message);
$this->printFooter();
}
}
Let us have a look at the controller component. I found some imple-
mentations of the MVC-pattern for PHP (like the MVC-pattern at [11])
that have a separate class for the controller part. That class is used in the
PHP-file the user requested. This suggests that the controller class is the
controller component of the MVC-pattern. This is not a nice way to apply
this pattern to PHP.
In this way the controller class is just a subset of the functionality of the
controller component. The controller class and PHP file together are the
controller component in the MVC-pattern. Because the functionality done
in the PHP file, also belongs to the controller, it is the part that interacts
with the user.
A better way of applying the MVC-pattern is to look at the PHP-file as
the controller component, so the controller component is the PHP-file itself:
Continuing the implementation example:
The Controller Component(index.php):
// initialize the model
$model = new ShoppingModel();
// initialize the view
$view = new ShoppingView($model);
// Check what action is defined in the URL
switch ($_GET[’action’]) {
// Show a product
case ’show_product’:
$view->printProduct($_GET[id]);
break;
// Add a product
case ’add_product’:
$model->addProduct($_GET[id],$_GET[name],$_GET[desc],$_GET[price]);
$view->printMessage(’Product added!’)
break;
default:
$view->printMessage(’No action found!’)
break;
}
So possible calls to this PHP-page:
• Show product with id 5:
index.php?action=show_product&id=5
• Add the candy bar to the products:
index.php?action=add_product&id=10&name=Candy%20bar&descr=…
These calls are normally made by the same (if you extend this controller)
or other controllers(read: PHP-pages) with the same model and view.
With this implementation we have a separation of the model, view and
the controller. As you can see now, it is rather easy to plug-in a new View
class resulting in a new UI for your web application.
4 SessionObject pattern
All the previous patterns are projections of existing pattern onto PHP. I
mean, they are general (and mostly Object Oriented) patterns that are
adapted to be used in PHP. The now following pattern is a new pattern
that I would like to introduce. It is a solution that I have used very often
in my history as a web programmer.
Name: SessionObject
Problem: You are programming a web application that makes use of ses-
sions and you want to remember the information about the session
(throughout the session) in an organised and structured way. E.g.
keep the shopping basket content available throughout the session in
a web shop.
Context: Web applications with sessions. Session information has to be
available throughout the session.
Solution & Consequences: Create a class definition that represents the
information that needs to be available throughout the session. At the
top of each PHP-page:
• Start or continue a session.
• Register a session variable(for holding the session object)
• Check if a session object exists, if not: create an instance of the
class(defined earlier) and assign it to the session variable.
Now you can always access the session information in an organised
way(via an object) and that object will be available during the whole
session.
Normally objects do not live very long in php, because they only exist
during the time of processing the PHP-page (mostly just a fraction of
a second). When you call a page, the objects are created and they
are used for the processing of the page. After the result has been sent
back to the user, all variables, including the objects, will be lost. With
this pattern you register an object as a session variable. That means
that, after the processing of the page, the object is stored in a textfile
together with the rest of the sessioninformation. At the time you that
you load the session again(in another pagerequest), the object will be
loaded again and will be available in your application.
Implementation: Let us have a look at an example of an implementation.
This is a stripped version of a ShoppingBasket object that I used in
web shops strore the products chosen / selected by the user. In this
example I make use of a well known ShoppingBasket pattern.
//
// This class stores the selected products
//
class ShoppingBasket {
var $productArray;
var $numberOfProducts;
…
//
// Adds a product to the productArray
//
function addProduct($id) {
// Add product with id=$id to the productArray
…
}
//
// Returns the array with the selected products
//
function getProductArray() {
return $productArray;
}
…
}
Your PHP-pages have to begin with this(because the function session start()
must be called before any output is written):
// If a session already exist: load session variables or create a new session if none exists.
session_start();
// Register the ShoppingBasket object as a sessionvariable
session_register(basket);
// If the basket-object does not exist, create one
if (!IsSet($basket)) {
$basket = new ShoppingBasket();
}
// Use the ShoppingBasket
$basket->addProduct(5);
$basket->addProduct(7);
$products = $basket->getProducArray();
If you have more than a few pages you could make a procedure (e.g.
my session start()) containing these lines. Then you just have to call my session start()
at the beginning of each page.
I tried to mix this pattern with the singleton pattern. My idea was to
make the ShoppingBasket-object a singleton, so you do not have to check
for the existence of an instance in the PHP-pages. But unfortunately this
does not work like that in PHP. This because of the fact that the static
instance variable in the loaded class (the session class) is different to the
static instance variable of our class definition in the PHP-file.
Problem and Pattern matching
In the beginning of this essay I stated some common problems. Afterwards
I introduced a few PHP-patterns. In this section I want to make a matching
of problems to a few important patterns.
Multiple presentations MVC pattern see 7.3
Navigation this is not a typically PHP problem, for navigational patterns
see [6] and [9]
Database operations Adaptor pattern (GoF) see [1] (convert the database
interface to an easy to use interface by making use of an adaptor class)
not discussed in this essay, but the Adaptor pattern is easy to project
on PHP.
Authentication and sessions SessionObject pattern see 7.4
These are some matchings that I find very usefull. This is not inteded
to be an exhausting list.
Conclusion
At first sight projecting known patterns to PHP looks quite easy. But if
you take a closer look and try to implement such patterns in PHP you will
probably figure out that there are some more problems to solve than you
thought of in the beginning. That is why there are a lot of PHP patterns
floating over the internet with poor quality.
These problems are mainly due to the fact that PHP is not a real object
oriented language and that the most patterns are object oriented. So we
can conclude that patterns depend on language expressiveness. In the fu-
ture it will be easier to map these(OO-) patterns to PHP because with the
introduction of newer versions the OO support in PHP will become more
mature.
