SINGLETON — PHP

Uğur Müslim
3 min readNov 25, 2020

--

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;

--

--

Uğur Müslim
Uğur Müslim

Written by Uğur Müslim

Software developer, guitar player, drinks mostly tea and water. Lately reads history books. Trying to get away from fiction.

Responses (2)