How to make a Singleton Design Pattern in PHP
Categories - Laravel PHP Framework PHP Tags - PHP Laravel   Maniruzzaman Akash   2 years ago   4856   4 minutes   28

How to make a Singleton Design Pattern in PHP

Today, we'll discuss about Singleton Design Pattern of PHP. Let's make this pattern simple and very easy to use.

What is Singleton Design Pattern - 

Singleton Pattern is a creational design pattern, which ensures that only one object of that class exists and provides a single point of access to it for any other code.

 

So, first when we've to use this Singleton pattern ? Problems are in some scenerios -

  1. If we don't want to recreat any object second time, then we need to use a way like Singleton.
  2. If there is a possibility of Memory optimization and one specific class must call one time, then we use singleton pattern.

 

Create a Singleton Design Pattern Class:

Let's start coding with creating a Singleton class.

<?php

class SingletonPatternExample
{
    /**
     * Singleton Instance
     *
     * @var SingletonPatternExample
     */
    private static $instance;

    /**
     * Private Constructor
     *
     * We can't use the constructor to create an instance of the class
     *
     * @return void
     */
    private function __construct()
    {
        // Don't do anything, we don't want to be initialized
    }

    /**
     * Get the singleton instance
     *
     * @return SingletonPatternExample
     */
    public static function getInstance()
    {
        if (!isset(self::$instance)) {
            self::$instance = new self();
        }

        return self::$instance;
    }
}

So, creating a singleton pattern class needs these staffs - 

  1. A private instance object variable.
  2. Constructor should be private as we don't want to instantiate from any other class
  3. A static method like getInstance(). Which logics are above example -
    1. If No instance found, or instance is null
    2. It will return the instance
    3. Otherwise create an instance
    4. and Return the instance

 

Let's improve our Singleton class a little more to make it more stable - 

<?php

class SingletonPatternExample
{
    /**
     * Singleton Instance
     *
     * @var SingletonPatternExample
     */
    private static $instance;

    /**
     * Private Constructor
     *
     * We can't use the constructor to create an instance of the class
     *
     * @return void
     */
    private function __construct()
    {
        // Don't do anything, we don't want to be initialized
    }

    /**
     * Get the singleton instance
     *
     * @return SingletonPatternExample
     */
    public static function getInstance()
    {
        if (!isset(self::$instance)) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    /**
     * Private clone method to prevent cloning of the instance of the
     * Singleton instance.
     *
     * @return void
     */
    private function __clone()
    {
        // Don't do anything, we don't want to be cloned
    }

    /**
     * Private unserialize method to prevent unserializing of the Singleton
     * instance.
     *
     * @return void
     */
    private function __wakeup()
    {
        // Don't do anything, we don't want to be unserialized
    }

    /**
     * Do something
     *
     * @return void
     */
    public function doSomething()
    {
        // Do something other stuffs
    }
}

So, now we've called two more magic methods of PHP and make them private, so that never ever the class could be cloned or instanciate double times.

  1. __wakeup() - Prevents serialization
  2. __clone() - Prevents duplication

 

How to call Our Singleton Class:

So calling Singleton class is simple - 

<?php

// We can't instantiate like this - It will create an error
// $singletonPattern = new SingletonPatternExample();

// We have to call getInstance() static method
$singletonPattern = SingletonPatternExample::getInstance();

// Check the object
var_dump($singletonPattern);

// Call our doSomething() method.
$singletonPattern->doSomething();

 

So, we've seen, we never call a singleton class using new.

$singletonPattern = new SingletonPatternExample();

 It will throug an exception.

 

We've to use getInstance() method to instantiate it.

// We have to call getInstance() static method
$singletonPattern = SingletonPatternExample::getInstance();

 

And we can access now any other method from the instance like - 

$singletonPattern->doSomething();

 

Make a Trait of Singleton Class and use it any class easily. Let's do that.

 Create a trait called Singleton in Singleton.php

<?php

trait Singleton
{
    /**
     * Singleton Instance
     *
     * @var Singleton
     */
    private static $instance;

    /**
     * Private Constructor
     *
     * We can't use the constructor to create an instance of the class
     *
     * @return void
     */
    private function __construct()
    {
        // Don't do anything, we don't want to be initialized
    }

    /**
     * Get the singleton instance
     *
     * @return Singleton
     */
    public static function getInstance()
    {
        if (!isset(self::$instance)) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    /**
     * Private clone method to prevent cloning of the instance of the
     * Singleton instance.
     *
     * @return void
     */
    private function __clone()
    {
        // Don't do anything, we don't want to be cloned
    }

    /**
     * Private unserialize method to prevent unserializing of the Singleton
     * instance.
     *
     * @return void
     */
    private function __wakeup()
    {
        // Don't do anything, we don't want to be unserialized
    }
}

 

Now, in class, where we want to use this, use just like this - 

<?php


class SingletonPatternExample
{
    use Singleton;

    /**
     * Do something
     *
     * @return void
     */
    public function doSomething()
    {
        echo 'Do Something...';
    }
}

 

And You can create any Singletonable class using that trait very easily. 

Like we want to make UserSeeder class to Singleton - 

<?php

class UserSeeder
{
    use Singleton;

    /**
     * Seed Users
     *
     * @return void
     */
    public function seed()
    {
        echo 'Seeding...';
    }
}

 

So, we can now easily re-use this Singleton trait across any of our classes and it would be very much helpful for our projects and we can follow the DRY(Do not Repeat Yourself) concept.

 

 

Tags: How to make a Singleton Design Pattern in PHP, Singleton pattern, PHP singleton design pattern, Design pattern PHP, How to create singleton design pattern in PHP, Singleton design pattern example, singleton in php

Previous
PHP If-else-elseif and Switch-case
Next
PHP String Functions - All necessary String functions in PHP to manage strings better.