Quick and Easy PHP Singleton

Published by JohnoTheCoder on

Hi guys

A really short one today, just because someone asked me about it a couple of days ago. I also though it potentially best to avoid something as controversial as my last post about Eloquent and the Single Responsibility Principle, which caused a bit of a stir during the week.

So, you want to make sure you only ever use one specific instance of a class (maybe a DB connection) and need a quick and easy way to do it. Personally, this is the technique I would use:

<?php

class MySingleton{
  
  // This will hold the instance of the class
  private static $instance = null;
  
  // Declare this as private to stop anybody being able to use the "new" keyword
  private function __construct()
  {
    // Your usual constructor stuff in here
  }

  // This is where you get your instance
  public static function getInstance()
  {
    if(is_null(self::$instance)){
      self::$instance = new self();
    } 
    return self::$instance;
  }

}

All we’re doing here really, in a set of steps:

  • You need a way to hold an instance of the object which is persistent throughout the execution
    This is what the private static $instance is doing
  • You don’t want anybody to be able to directly use the new keyword, because then you’ve lost control of the instances of the object
  • You need to be able to get an instance of the class, which is what the getInstance method is for
  • In getInstance all we’re doing is instantiating the object if one hasn’t get been stored against the $instance static

So, to fetch your instance is simply:

$singleton = MySingleton::getInstance();

Wherever you run that throughout your code you will receive the exact same instance. Particularly useful in things like Database connections, loggers/debuggers and things like that.


JohnoTheCoder

Programmer and Web Developer. Biker. Father. Lover of boxing and stand up comedy.

4 Comments

johnothecoder · 2nd September 2017 at 12:47 pm

Disclaimer: Don’t use singletons unless you’ve got a really good reason to

Note: It would appear that this topic is no less controversial than my last

Friendly developer · 2nd September 2017 at 9:23 pm

General issue: missing a private __clone method, without that the instance can be cloned, therefore the Singleton instance is not granted.

Optimizations:
1. null assignment for $instance is not needed, all variables declared are null by default.
2. null === $check is faster than is_null($check).
3. Should use phpdoc for methods instead of inline comments, speaking of: missing type hint of $instance and return value of getInstance in phpdoc.

johnothecoder · 2nd September 2017 at 10:52 pm

Hi FD,

I thought I’d number my points back so it made sense

Absolutely fair point. Completely forgot about __clone
I didn’t realise that it was any faster, but I know now for next time, thanks for that
I normally do phpdoc and type hint, I wrote this straight into the WYSIWYG so I didn’t code as I normally would (type hinting assumes I’m working/deploying somewhere with PHP7 of course)

In hindsight, I might write into my IDE first, then C&P it into the editor for the post, it’ll stop me making newb-looking errors because I wrote syntax into a text editor haha

Thanks!
Johno

Layering Software Design on new or existing code bases · 3rd June 2018 at 2:03 pm

[…] that, for the purpose of this shared functionality, you want to make this layer interface through a singleton, particularly if the class itself is doing very little besides providing anaemic functionality to […]

I'd love to hear your opinion on what I've written. Anecdotes are always welcome.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: