Singletons and their use in WordPress

Today is one of those WordPress days. You’re sitting down at your computer. You’ve got a plugin you want to write. You’ve heard that object-oriented programming is pretty awesome so you want to use it (obviously).

You create your plugin folder. You add your empty “index.php” (right?). You create your “WP_Kickass_Plugin” class in “kickass-plugin.php”. Sweet, you’re in business. Time to get into the meat of things.

You’ve got some actions and filters you want to use. You need to register them somehow. WordPress developers have two “traditional” ways to solve the problem.

One way is to register everything in the class constructor. You’ve got access to the instantiated object at that point so it’s easy to pass it along to WordPress.

The other popular way is to instantiate an object outside the class. You use that instance to register your actions and filters.

The issue with both these approaches is that there’s no easy way to get that object back after. You’ve orphaned that object unless you store it as a global. Storing that object as a global is far from ideal. You’re vulnerable to overwriting something or someone else overwriting your object.

Enter the singleton

The singleton pattern is how a lot of WordPress developers worked around that problem. It’s a software design pattern limits a class to a single (ha!) instantiated object. There’s three elements to a class implementing the singleton pattern. You have to:

  • Have a private static variable to store the instantiated object.
  • Make the constructor private.
  • Create a public static method (usually named “get_instance”) to get the instantiated object.

Let’s see how you’d code the singleton pattern in the plugin class we created earlier.

Using the singleton pattern

Let’s go over both our earlier examples. You can convert them to a singleton by following the steps outlined above. The resulting code is close to the original one. Our first example used the constructor to register all the actions and filters. You can see the converted code below.

Converting it to a singleton required a few changes. We made the constructor private and added the static variable and the “get_instance” method.

The second one registered everything outside the class. The result is almost the same as the previous example.

We needed to create an empty private constructor. That’s because constructors are public by default. Another side effect of the private constructor is that we can’t create our object using the new keyword. We need to pass it to the register functions by calling “get_instance”.

It’s worth noting that the singleton makes that second method a lot less appealing to use. The singleton pattern is more interesting if you’re registering the hooks inside the constructor.

How it fits in the WordPress world

The truth is that using objects in a WordPress plugin (or theme) is challenging. If you’d used functions, you wouldn’t have any of those headaches. Boring old functions are available anywhere and anytime (as long as your plugin is active).

With the singleton pattern, your class looks a lot like those easy to use functions. You have easy access to your plugin object(s) at any time. All you need to do is call “get_instance”.

Singletons are easy to overuse

You can get addicted to the singleton pattern. It’s simple to implement and solves a big problem in WordPress. It makes you feel safe. Your object is always one method away. There’s just no saying no to the sweet siren song of “get_instance” (even I couldn’t at first).

Next thing you know, all your classes implement the singleton pattern.

Let’s get philosophical for a moment

If everything is important, then nothing is.

– A wise designer

This is a great quote that anyone doing CSS can relate to. I think it’s great in the context of singletons as well. If everything is a singleton, then why have a class in the first place?

You’re cutting out a critical part of what makes object-oriented programming. The ability to instantiate multiple objects from a class.

What was the singleton designed to solve?

The singleton solves a specific problem. That’s how to access a shared unique resource. In this case, a shared resource is something like RAM, a log file or a port. These are all resources where the operating system will limit their access to one process.

Let’s imagine if your code opened a file and locked it. If you instantiated another object to access that same file, what would happen? You’d get an error or worse a corrupted file. You need to get the same object that has the file locked.

This isn’t a scenario you’ll see in PHP often. It’s only meant to illustrate the type of problem that the singleton pattern solves. Your plugin classes aren’t a shared resource. The singleton pattern isn’t quite the tool you want to use for this problem.

Breaking up with the singleton pattern

Obviously, having a way to get the object you gave WordPress is important. How do we move away from the singleton while solving that problem? Let’s take a look at a few things you can start doing today to wean yourself off.

Give your class everything it needs to do its job

This comes from the single responsibility principle. You need to divide your classes by responsibility. Each class must have all the information it needs internally.

This removes a lot of the dependence on “get_instance”. Your class is self-sufficient already so there’s no need to get the object. The issue becomes how to build a plugin that way.

There’s a detailed example in the single responsibility article linked earlier. It shows you how to build a plugin with classes divided by responsibility.

Take plugin API code out of the constructor

The role of the constructor is to prepare the object for use. Registering actions and filters with the plugin API doesn’t fit that task at all. What you want to do instead is use a static method to create the object and register everything there. Here’s how it would look like in our earlier example.

Removing the registration from the constructor removes the strongest reason to use a singleton. This makes your class more decoupled from the WordPress code. The only issue is that you can’t alter the object once it’s registered.

You’ll notice that the constructor is now public as well. There’s no need to keep it private anymore. Your hooks aren’t called there anymore. This means that instantiating a new object has no effect on WordPress anymore.

These changes have another positive benefit. It makes your class unit testable. That’s great if you’re trying to maintain a bug free plugin.

Split the plugin API into its own class

This is a more advanced way to overcome the use of the singleton pattern. The idea is to the decouple the use of the plugin API from all your classes. You make a class whose sole responsibility is to interact with it.

This is what I had in mind when I put together the example for using interfaces. Creating that class removed the need to use “add_action” and “add_filter” in other classes. We’re using the plugin API here, but you should do it for any API you rely on a lot in your plugin.

It’s worth knowing about the singleton pattern

That said, using it is a choice. You don’t have to. There’s various ways for you to get around the problem(s) that the singleton solves.

Solving them just requires that you think outside the box.

9 thoughts on “Singletons and their use in WordPress”

  1. Thanks for the informative article. I’ll definitely give it another read as I’ve mostly used the first approach.

    The main reason I wanted to chime in was the comment within the private constructor:

    // So ronery…

    Singletons f*ck yeah!

  2. Shouldn’t the constructor be private in order to avoid to create an instance ? (line 20 of last code sample)

    Otherwise, I don’t get what is the plus-value of the proposed method. What I like about using a true Singleton is that only one instance of the object can be created and I can make sure that I am the only one to instantiate it.

    I get your point about the origin of the Singleton but I think using it to create an instance (and only one) for my plugin is a way to make sure nobody messes with my plugin by creating multiple instances. Much more if you enable other developers to hook to it!

    1. Instantiating a second plugin class actually does nothing in this scenario. That’s why the constructor can be public. Making it public is important though.

      What if you want to create the object without the hooks? This is a real scenario if you’re unit testing your plugin for example. Your hooks aren’t something that need to be called for your unit tests (except to test hook registration).

      If you don’t trust your plugin users, I’d add a static variable to create a flag for the “register” method. You can then use it to track if the class was registered with WordPress. If it’s registered, don’t do it again. You can even store the object if you’d like. Doing so doesn’t make it a singleton. It simply represents the reality that you want the object registered with WordPress.

      I think hooks are the correct way for other developers to interact with your plugin. We’ll see that later when we see other patterns.

      1. I agree that in your specific code (that does nothing!) that it does not change anything. But it could easily have an impact if you keep a status in a variable for instance. You do not need to ad alot of complexity to get the problem.

        I’d rather create a “registerWithoutHooks()” method or add a parameter in order to avoid to give access to the constructor.

        I agree it’s easy to have too many singleton or to use static methods instead of object instances!

        1. I think there’s nothing evil with a public constructor if it does what it’s supposed to do. Setup the object. If you made that object self-sufficient once it’s registered, there’s no need to have direct access to it.

          To go back to your status variable or any other behaviour. You mentioned it yourself. Use actions and filters! It’s super powerful and not used to even half its potential.

          Designing a plugin to be “event driven” is something that’s in my mental backlog. Doing it that way, you wouldn’t need to do anything but register your event listener classes.

  3. add_action(‘wp_enqueue_script’, array($this, ‘enqueue_script’));
    should read

    add_action(‘wp_enqueue_scripts’, array($this, ‘enqueue_script’));
    🙂

Comments are closed.