How to make a Singleton Design Pattern in PHP
Categories - Laravel PHP Framework PHP Tags - PHP Laravel   Maniruzzaman Akash   1 week ago   182   0

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
#5 Laravel Views
Next
React Context API - An Advanced Introduction and Complete Examples