<? echo

Project Statuses

Mental Fusion - 85%
FusionBB - 2%
This webpage is built with W3C compliant HTML5.
This webpage is built with W3C compliant CSS3.
Download: Fast, Fun, Awesome
Opera, the fastest and most secure web browser

Example Information

The Singleton Design Pattern

Posted: February 10, 2012 12:08 PM CST by Michael
So, it was recently brought to my attention that there is a such thing as a Singleton design pattern for PHP. I hadn't heard of it before, so I did a little research on it.

Surprisingly, it's a pretty simple concept. The idea is that any instance of a Singleton object after the first initialization will always return the same instance of the object; effectively, only one instance of the object will ever exist, even if the variable is renamed or what have you.

So how do we create a Singleton object? First, we need to set up our PHP Singleton class. For this, I've created a file called 'Singleton.Class.php.' Its contents are below:

<?php
/**
*
* Example Singleton Class by Michael L. Brown
*
**/

// define the class name
class Singleton {

// define our static instance variable; this *must* be static:
private static $instance;

// define any other variables; for this example, a private counter variable:
private $count = 0;

// define our construct function
private function __construct() {}

// define our instantiation function; this will ensure only one instance of this object exists:
public static function createInstance() {
// check to see if an instance of self exists:
if (!isset(self::$instance)) {
// if it doesn't exist, create it:
$class = __CLASS__;
self::$instance = new $class;
}

// the default response returns the instance that either already existed or was created above:
return self::$instance;
}

// define our increment function to increment the counter:
public function inc() {
// output the counter and increment it by 1:
echo $this->count++;
}
} // end of class
?>

So, what does it all mean? Let's start at the top with the declaration of private static $instance. private means that this variable is not accessible outside of the class object. So you cannot directly call Singleton::$instance unless you're within the class. To reference $instance within the class, we use the identifier self as $this isn't available without an instance of the object.

static means that the variable is accessible without an instance of the class object being created. This works for both properties and methods and is required for building our Singleton class as Singletons cannot be created with the new operator (that would negate the entire point of a Singleton). For this reason, our __construct() function is declared private.

Next we have the actual meat of the Singleton. public static function createInstance() will check to see if the $instance property is set. If not, the Singleton will create an instance of itself by setting the private static $instance property to an instance of itself by calling the Singleton class via the new operator (this goes back to why the __construct() function needs to be private). After creating the Singleton, or after determining it already exists, the createInstance() function will return the instance of itself.

Now that the meat is done, we can add any necessary functions to achieve our ends. In this case, a simple public function called inc() is created to echo and increment the counter variable we set up earlier.

From here, we can test it out. To test, I put together the following file:

<?php
include('Singleton.Class.php');

// creates a new instance of our Singleton object:
$objTest = Singleton::createInstance();

// Let's try out the inc() function a few times to see what happens:
$objTest->inc(); // outputs 0
$objTest->inc(); // outputs 1
$objTest->inc(); // outputs 2

// But what if we try to create the object again as a different variable?
$objTest2 = Singleton::createInstance();

// What happens when calling inc() now?
$objTest2->inc(); // ouputs 3
$objTest2->inc(); // ouputs 4
$objTest2->inc(); // ouputs 5
?>

In this example, the Singleton class is included and then instantiated as $objTest. $objTest->inc() can now be used to call the inc() function within the Singleton class.

So, how does this behave? When the first instance is created, the output of inc() starts at 0 and increments each time as expected. But what happens if another Singleton object is created? When $objTest2 is created, the original instance created in $objTest is returned and subsequent calls to inc() further increment the counter variable as opposed to starting at 0.

This can be both highly useful and highly dangerous/unstable if used in the wrong application setting, but it's still a pretty neat idea.
; ?>