SINGLETON — PHP
Singletons are really important. They help us with code efficiency, performance problems, getting rid of unnecessary object creations. Let’s go into examples;
For example, you will make a database connection. Instead of connecting in every time a query is called what if you connect to the database once and use it. It is one of the solutions.
<?php
class DBConnection
{
static private $instance = null;
private $conn;
private $servername = "localhost";
private $password = "example";
private $name = 'exampleDB';
private $username = "exampleUser";
public static function getInstance()
{
if (!self::$instance) {
self::$instance = new DBConnection();
}
return self::$instance;
}
private function __construct()
{
try {
$this->conn = new PDO("mysql:host=$this->servername;dbname=$this->name", $this->username, $this->password);
// set the PDO error mode to exception
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
} catch (PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
}
public function getConnection()
{
return $this->conn;
}
private function __clone()
{
}
}
So when you run getinstance() function, it will first check if it was initialized before. If it was initialized, it won’t bother with doing this thing again.
$connection = DBConnection::getInstance();
$connectionGet = $connetion->getConnection();
No matter how much you call DBConnection::getInstance there will be one instance as we wanted.
Let’s think about this class. It is not singleton. And it will create a new connection every time we call.
<?php
class DBConnectionNotSingleton
{
private $conn;
private $servername = "localhost";
private $password = "example";
private $name = 'exampleDB';
private $username = "exampleUser";
function __construct()
{
try {
$this->conn = new PDO("mysql:host=$this->servername;dbname=$this->name", $this->username, $this->password);
// set the PDO error mode to exception
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
} catch (PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
}
public function getConnection()
{
return $this->conn;
}
private function __clone()
{
}
}
?>
THINGS TO BE CAREFUL ABOUT
But we must say that, every php script run will create its own instance. It is not like NodeJS or C#. I’ll write about them too but for now it is just about PHP. Let me show you what I am trying to say.
Let’s write a simple ‘Number Add’ Class. It will be a singleton, so what we expect is, when we add to the number in class, because it is the number in same object it we will see the progress in every call.
<?php
class NumberAdd
{
static private $instance = null;
private $singletonNumber = 0;
public static function getInstance()
{
if (!self::$instance) {
self::$instance = new NumberAdd();
}
return self::$instance;
}
private function __construct()
{
}
public function AddToNumber($numberToAdd = 1)
{
$this->singletonNumber += $numberToAdd;
return $this->singletonNumber;
}
public function getNumber()
{
return $this->singletonNumber;
}
private function __clone()
{
}
}
And I call this class by saying below code;
<?php
include ("NumberAdd.php");
$number = NumberAdd::getInstance();
var_dump($number->AddToNumber());
$number = NumberAdd::getInstance();
var_dump($number->AddToNumber());
$number = NumberAdd::getInstance();
var_dump($number->AddToNumber());
$number = NumberAdd::getInstance();
var_dump($number->AddToNumber());
Every time I run the script I am getting these same results.
int 1/RunNumberAdd.php:8:int 2/RunNumberAdd.php:11:int 3/RunNumberAdd.php:14:int 4
So when a script runs and finishes, singleton goes away. This is different in other languages . I’ll get to them in future articles.
WHAT IF WE DON’T USE SINGLETON IN NUMBER ADD
We ll see the results like this;
<?php
include ("NumberAddWithoutSingleton.php");
$numberAdd = new NumberAddWithoutSingleton();
var_dump($numberAdd->AddToNumber());
$numberAdd = new NumberAddWithoutSingleton();
var_dump($numberAdd->AddToNumber());
$numberAdd = new NumberAddWithoutSingleton();
var_dump($numberAdd->AddToNumber());
$numberAdd = new NumberAddWithoutSingleton();
var_dump($numberAdd->AddToNumber());/RunNumberAddWithoutSingleton.php:5:int 1/RunNumberAddWithoutSingleton.php:8:int 1/RunNumberAddWithoutSingleton.php:11:int 1/RunNumberAddWithoutSingleton.php:14:int 1
By the way there is good post about singleton vs static performance. It states that static function usage will make your script faster but it does not mean that it is useless at all.
Useful articles;