Singleton pattern is used to ensure that only an instance of a class is created. Each time an attempt to create an instance of the class will return the same instance.
NOTES
In this article, we are discussing the implementation of the Singleton Pattern in PHP. Implementation of the Singleton pattern in PHP follows the same steps as Java and TypeScript.
See the Singleton in other languages in the “Other Code Implementations” section. Or, use the link below to check the details of the Singleton Pattern-
Implementation
Follow the steps below for Singleton pattern implementation in PHP-
- Create Singleton class. We need to make sure that an instance of this can not be created outside of the class.
- Define the construction of the class as private, so that an instance can not be created directly using the “new” keyword.
- Define a class property as of the type of the same class, this property will hold an instance of the Singleton class.
- Create a method for generating instance. If an instance already exists then return that, if the instance does not exist then create new instance, then create a new instance and return that.
Here is a simple example of Singleton pattern implementation in PHP-
<?php
// Singleton pattern implementation in PHP
class Singleton {
// Make sure to make the "private" and "static"
private static ?Singleton $singletonInstance = null;
// Make sure to make the constructor "private"
private function __construct(private string $someVal) {}
// Make sure to make the function "static"
public static function getInstance(string $someVal): Singleton {
// Check if an instance already exists
if (!self::$singletonInstance) {
// If instance does not exist then create an instance
// and assign that to "singletonInstance"
self::$singletonInstance = new Singleton($someVal);
}
// Return the "singletonInstance"
return self::$singletonInstance;
}
public function printDetails() {
echo "\nsome val: " . $this->someVal;
}
}
// Demo
// Use the singleton implementatin like below
$mySingletonInstance = Singleton::getInstance("abc");
$mySingletonInstance->printDetails();
// Try using another instance
$anotherInstance = Singleton::getInstance("changed val");
$anotherInstance->printDetails();
// New instance can not be created using the "new" keyword
// as the constructor is declared as "private".
// An attempt like below will generate error
// const someSingletonInstance = new Singleton();
Following output will be generated-
some val: abc
some val: abc
Examples
Here are a few examples of PHP-
Example #1: Database Connection
For this example, let’s consider the creation and management of a database connection.
Here we are using Singleton pattern, so that the same instance is returned always, and the same connection can be always used.
DB Connection Singleton Class
- Create file “DbConnSingleton.php”.
- Create class “DbConnSingleton”.
- Define property named “singletonInstance” of type of the same class “DbConnSingleton” and set it to null.
- Define constructor as private. Accept values for “host”, “port”, “username” and “password” and set that to class property of the same name.
- Create method “getInstance” which accepts param to create an instance. Check if the value of “$singletonInstance” if already set or not. If already set then return that. If instance is not set, then create a new instance and then return that.
- Define utility methods “printConnectionDetails” to print connection details.
<?php
// DbConnSingleton.php
namespace BigBoxCode\DesignPattern\Singleton\DbConnection;
class DbConnSingleton {
private static ?DbConnSingleton $singletonInstance = null;
private function __construct(
private string $host,
private int $port,
private string $username,
private string $password
) {
}
public static function getInstance(string $host, int $port, string $username, string $password): DbConnSingleton {
if (self::$singletonInstance) {
echo "\nUsing existing db connection instance";
return self::$singletonInstance;
}
echo "\nCreating new db connection instance";
self::$singletonInstance = new DbConnSingleton($host, $port, $username, $password);
return self::$singletonInstance;
}
public function printConnectionDetails() {
echo "\nhost:" . $this->host;
echo "\nport:" . $this->port;
echo "\nusername:" . $this->username;
echo "\npassword:" . $this->password;
}
public function executeQuery($query) {
echo "\nExecuting query: " . $query;
}
}
Demo
Create an instance of the “DbConnSingleton”, by sending some value of host, port, username, and password to the method “getInstance”.
Then if we try to create another instance of “DbConnSingleton” instance by calling the “getInstance” method.
If we check the connection details then we fined that, it has the same connection as the previous one.
<?php
// demo.php
require __DIR__ . '/../../vendor/autoload.php';
use BigBoxCode\DesignPattern\Singleton\DbConnection\DbConnSingleton;
// Create database instance
$dbConnOne = DbConnSingleton::getInstance('loclahost', 1234, 'root', 'secret!pass');
echo "\nDB connection details for dbConnOne:";
$dbConnOne->printConnectionDetails();
// Try to create another database instance
$dbConnTwo = DbConnSingleton::getInstance('192.168.55.55', 2222, 'root2', 'secret!pass2');
echo "\nDB connection details for dbConnTwo:";
$dbConnTwo->printConnectionDetails();
Output
Following output is generated by the above code-
Creating new db connection instance
DB connection details for dbConnOne:
host:loclahost
port:1234
username:root
password:secret!pass
Using existing db connection instance
DB connection details for dbConnTwo:
host:loclahost
port:1234
username:root
password:secret!pass
Example #2: Setting
Let’s check another example of the setting or configuration values of the application.
Setting Singleton Class
- Create file “Setting.php”.
- Create class “Setting”.
- Define property named “settingInstance” of type “Setting”.
- Define an array “props” to store setting properties.
- Make the constructor as private.
- Create method “getInstance”. Check if the value of “$settingInstance” already exists or not. If not set, then create a new instance. Then finally return the instance.
- Define methods for getting and setting the properties.
<?php
// setting.php
namespace BigBoxCode\DesignPattern\Singleton\Setting;
class Setting {
private static ?Setting $settingInstance = null;
private $props = [];
// Make sure to define a private constructor
private function __construct() {
}
public static function getInstance(): Setting {
if (empty(self::$settingInstance)) {
self::$settingInstance = new Setting();
}
return self::$settingInstance;
}
public function set(string $key, mixed $value): void {
$this->props[$key] = $value;
}
public function get(string $key): mixed {
if (isset($this->props[$key])) {
return $this->props[$key];
}
return null;
}
public function getAll() {
return $this->props;
}
}
Demo
Use the method “getInstance” to create a new instance of the setting class.
<?php
// demo.php
require __DIR__ . '/../../vendor/autoload.php';
use BigBoxCode\DesignPattern\Singleton\Setting\Setting;
// Create setting instance
$setting = Setting::getInstance();
$setting->set("file_base_path", "/var/log/dd");
$setting->set("app_port", 3000);
var_dump($setting->getAll());
// Try to create another instance
$setting2 = Setting::getInstance();
var_dump($setting2->getAll());
Output
array(2) {
["file_base_path"]=>
string(11) "/var/log/dd"
["app_port"]=>
int(3000)
}
array(2) {
["file_base_path"]=>
string(11) "/var/log/dd"
["app_port"]=>
int(3000)
}
Source Code
Use the following link to get the source code:
Other Code Implementations
Use the following links to check Singleton pattern implementation in other programming languages.