rtCamp notes, day 53 of undefined

Singleton Pattern

The singleton pattern is not a WordPress feature, but a normal feature which most of the programming languages support [ idk if we call it a feature or something ].
What it exactly does?
As the name suggests -> Singleton -> Means its something associated to single?
Singleton class helps us have two amazing benefits of implementing it to any class.

  • We can restrict the class to have only one instance, no matter how many times it is called or from where it is called.
  • Can allow us to globally access the class -> no more needs of globally setting the variable object of the class and polluting the global environment

Singleton in PHP

Let’s start of with a quick example, lets create a class Person.

class Person {

	public $name;

	public function __construct() {
		$this->name = 'Aryan';
	}

}

Now how do I access the name for this? I will have to create an object and use it to access it

$person = new Person();
echo $person->name;

Now what if I want to call it from a different file where I have a huge codebase. Defining the $person globally is not a good approach as it can mess with the elements in the codebase. Now here comes the Singleton

class Person {

	public $name;

	private static $instance = null;

	private function __construct() {
		$this->name = 'Aryan';
	}

	public static function get_instance() {
		if ( null === self::$instance ) {
			self::$instance = new Person();
		}
		return self::$instance
	}

}

Now how do we get the instance?

$person = Person::get_instance();
echo $person->name;

Now even on the global scope we do not need to rely on the $person we can just use the Person::get_instance() to get the single instance.

Let’s look at how everything is working.

  • We are adding the private variable $instance which would store the object instance of our class.
  • We created a static function get_instance() this function is responsible for returning the instance of the class from the $instance private property, and it also sets the value of $instance to the new object of class if it is not already set [ this will execute only once, as the next time the instance would be there ]

Now the question comes, what if we create a new object of the class using new Person() -> Well this would not be possible 😛 cause we have defined the constructor as a private function, it can be only called from inside the class.

This is what happens when we try to create another object of it


Now we are using this singleton everywhere, ins’t the code repeating, is there any solution for it?

Yes, we can make use of the PHP traits for this, we can create a trait for Singleton and define our class to use it.
By definition traits means -> ‘Traits are a mechanism for code reuse in single inheritance languages such as PHP. A Trait is intended to reduce some limitations of single inheritance by enabling a developer to reuse sets of methods freely in several independent classes living in different class hierarchies’

In simple words, we can take it as we are extending the class from some other class, though we are not. Trait is basically we are composing the code at runtime.
Let’s see the working for it

Define a trait Singleton

trait Singleton{

	private static $instance = null;

	public static function get_instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

}

Now we can use this trait in our classes with a simple use keyword.

For example, let’s refactor the Person class with this trait.

class Person {

	use Singleton;

	public $name;

	private function __construct() {
		$this->name = 'Aryan';
	}
}

Yep, as easy as that.
Look how clean the code would look.
And this way we can add it to multiple classes without repeating the code.

Final code:

trait Singleton{

	private static $instance = null;

	public static function get_instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

}
class Person {

	use Singleton;

	public $name;

	private function __construct() {
		$this->name = 'Aryan';
	}
}

$person = Person::get_instance();
print_r( $person );

The output:

Leave a Reply

Your email address will not be published. Required fields are marked *