Using the Singleton Pattern in PHP or WordPress
Design patterns are useful solutions to common problems that someone might face when designing software. The Singleton Pattern is one such design pattern that can be employed in your software.
It falls into the creational category as parts of its pattern set out the expectations on how a given class can be created. The singleton also outlines how it can be retrieved as part of the same pattern.
If you just want to see the code skip to the Singleton example.
Do You Actually Need A Singleton?
This is the first question you should always ask yourself. Underlying problems are often what causes the desire to use a Singleton. Using a Singleton as a band-aid to a problem that can be solved easily is an anti-pattern.
Before you implement the Singleton pattern always ask yourself:
Do you really need it? Really?
If you cannot answer that question definitively with a ‘yes’ and explain why then chances are you don’t need it. If you think you need it but can’t explain why then that may be a code smell you should investigate.
Sometimes that smell comes from a 3rd party or legacy system and is not viable to fix. In that case, a Singleton can be your answer.
What problems does a Singleton solve?
A singleton exists to solves 2 problems. Single instances and single access points.
- To ensure that only a single instance of a given class can exist at any time.
- To provide a single accessible way of getting that same class instance.
Note: A concrete class created to solve 2 problems at the same time doesn’t adhere to the Single Responsibility Principle.
The fact that Singletons knowingly violate the Single Responsibility Principle is part of the reason that you need to know why you need a Singleton. If you’re going to violate a deep-rooted principle you should know why.
Why Would You Use a Singleton?
Singletons exist to solve two well-defined problems. Single instances and single access points. If you need to solve both of those problems a Singleton is absolutely the correct choice.
Single Instance
Single instances can often be needed for the entry point to a data source.
- A database where you need to control the connection count.
- An item on the filesystem that can handle only one operator at a time.
- A single point of truth in a larger system that others need to know about and call to.
Some of these are code smells and you should probably consider trying to solve the issue at a deeper level. It isn’t always simple to solve them – particularly with 3rd party or legacy systems.
Single Access
In a well-designed system classes of the same type should be able to hot-swap most of the time – but not always.
One exception is if they hold runtime data important to your application as a whole. Then you want to be able to get that data from across the entire application.
Singletons In WordPress
In WordPress we do have to solve both of these problems at once. This is partially caused by the events system – hooks. When you hook a method inside an object to an action or function as the callback you need to keep the object it was hooked with around.
If you don’t keep the object around then it can’t easily be unhooked later – either by you or by someone else.
A singleton is accessbile anywhere – some other plugin or developer can eaily get the instance to unhook something.
It can also be used as a data store – to hold onto other objects or bits of info you need. Sometimes a singleton can hold objects that hook in other objects to keep them accessible – meaning only 1 singleton is needed.
How to Implement the Singleton Pattern
Singleton takes advantage of some of the basic concepts of Object Orientated systems to create a class that acts in a special way.
- It uses
static
definitions to create a global way to get the instance. - Toggling
visibility
of methods and properties to ensure that creating new instances is not possible from an outside scope.
You start with a static property to hold an instance of the class. When the class is instantiated this holds an instance of self
. You access the property through a getter instead.
The getter is a static method that returns an already created instance from the static property or it creates an instance – storing it in the property for later – and returns it.
The final piece of the pattern is to set the constructor to private. A private constructor is not accessible from outside the class. That means you can’t instantiate the class with the new
keyword.
<?php
class MySingletonClass {
static $instance;
static get_instance() {
if ( null == self::$instance ) {
self::$instance = new self;
}
return self::$instance;
}
private function __construct() {
// do construction actions.
}
}
The class example above is the Singleton pattern in its entirety. There is nothing else to it. Using the class becomes a little different to how you normally instantiate classes.
You need to get its instance through a method rather than instantiate it with new
.
// This does not work and throws a fatal error.
$my_class = new MySingletonClass();
// This works.
$my_class = MySingletonClass::get_instance();