The singleton pattern is a design pattern that is used to restrict instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system.
Here is an example, that demonstrates this singleton pattern:
<?php
echo ” 1: “;
$user_1 = CurrentUser::singleton();
echo “\n 2: “;
$user_1->counter();
echo “\n 3: “;
$user_2 = CurrentUser::singleton();
echo “\n 4: “;
$user_2->counter();
echo “\n 5: “;
$user_1->counter();
echo “\n 6: “;
$post = new Post();
echo “\n 7: “;
$post->counter();
/* Singleton Class: CurrentUser */
class CurrentUser
{
// Hold an instance of the class
private static $instance;
private $counter = 0;
// A private constructor; prevents direct creation of object
private function __construct()
{
echo “Constructing CurrentUser \n”;
}
// The singleton method
public static function singleton()
{
if (!isset(self::$instance)) {
$c = __CLASS__;
self::$instance = new $c;
} else {
echo “<span class=\”ghost\”>CurrentUser already exists</span> \n”;
}
return self::$instance;
}
public function counter()
{
echo “CurrentUser -> counter = ” . $this->counter . ” \n”;
++$this->counter;
}
}
/* Normal Class: Post */
class Post
{
private $current_user;
public function __construct()
{
echo “Constructing Post \n “;
$this->current_user = CurrentUser::singleton();
}
public function counter()
{
echo “Post -> counter \n “;
$this->current_user->counter();
}
}
?>
In this code there is a class CurrentUser, which consists of one private and static variable to hold current user object and another private variable for counter.
This class consists of three functions,
1: The contructor – which is called when the class is instantiated
2: Singleton – it checks if the variable instantiate is set or not. If its not set then new object is created else it uses the existing object
3: Counter fn – to increment the counter variable.
Output of the code:
1: Constructing CurrentUser
2: CurrentUser -> counter = 0
3: CurrentUser already exists
4: CurrentUser -> counter = 1
5: CurrentUser -> counter = 2
6: Constructing Post
CurrentUser already exists
7: Post -> counter
CurrentUser -> counter = 3
Here is an example, without singleton pattern
<?php
echo “1: “;
$user_1 = CurrentUser::singleton();
echo “<br>2: “;
$user_1->counter();
echo “<br>3: “;
$user_2 = CurrentUser::singleton();
echo “<br>4: “;
$user_2->counter();
echo “<br>5: “;
$user_1->counter();
echo “<br>6: “;
$post = new Post();
echo “<br>7: “;
$post->counter();
/* Singleton Class: CurrentUser */
class CurrentUser
{
// Hold an instance of the class
private $instance;
private $counter = 0;
// A private constructor; prevents direct creation of object
private function __construct()
{
echo “Constructing CurrentUser \n”;
}
// The singleton method
public function singleton()
{
$c = __CLASS__;
$instance = new $c;
return $instance;
}
public function counter()
{
echo “CurrentUser -> counter = ” . $this->counter . ” \n”;
++$this->counter;
}
}
/* Normal Class: Post */
class Post
{
private $current_user;
public function __construct()
{
echo “Constructing Post <br>”;
$this->current_user = CurrentUser::singleton();
}
public function counter()
{
echo “Post -> counter<br>”;
$this->current_user->counter();
}
}
?>
In this example, the CurrentUser object is created each time when the singleton function is called.
The output of this code:
1: Constructing CurrentUser
2: CurrentUser -> counter = 0
3: Constructing CurrentUser
4: CurrentUser -> counter = 0
5: CurrentUser -> counter = 1
6: Constructing Post
Constructing CurrentUser
7: Post -> counter
CurrentUser -> counter = 0
Reference: Implementing a PHP Singleton
