Resources
singleton

Singletons

supergrecko#3434
July 27, 2019
1 minute read time

A singleton is a class which is only instantiated once during runtime. This is done by keeping a static property containing its instance on the singleton class.

There are multiple benefits to using a singleton class

  • You're always going to pull the same instance of the class
  • It's only instantiated once
  • Use $this in a static-like context

By using a singleton instead of a static class we expose a cleaner class to use and we can use regular instance properties instead of static properties.

Creating a Singleton in PHP

Creating a class which can be used as a singleton is very simple.

<?php

namespace Example;

class Singleton
{

    /**
     * The singleton instance
     * @var Singleton
     */
    private static $instance;

    /**
     * Get the instantiated singleton, or create it if it hasn't been instantiated yet.
     * @return Singleton
     */
    public static function getInstance(): Singleton {
        // In PHP 7.4 we will be able to do
        // static::$instance =?? new static();
        // The double ?'s is a null-coalesce operator. There's a link about it below.
        static::$instance = static::$instance ?? new static();

        return static::$instance;
    }

}

Testing our Singleton

To give a little functionality to our freshly baked Singleton we add these three members to the class

    private $word = "Pineapple";

    public function getWord(): string {
        // PHP_EOL is a constant for a new line (\r\n) or whichever your OS uses.
        return $this->word . PHP_EOL;
    }

    public function setWord(string $word): void {
        $this->word = $word;
    }

We are now ready to test our Singleton.

We'll start of by proving that only one instance is created during runtime. We'll grab the singleton instance twice using Singleton::getInstance(); and comparing their object ids using spl_object_hash. Let's try it!

$first = Singleton::getInstance();
$second = Singleton::getInstance();

// Compare the hash ids for each of the variables, if they are equal then they contain the same instance.
var_dump(spl_object_hash($first) === spl_object_hash($second)); // bool(true)

We can now prove its static-like functionality by using our getWord and setWord methods.

We will do this by comparing the returned value from getWord() on $first and $second.

var_dump($first->getWord() === $second->getWord()); // bool(true)

// now let's try chaning the value on $first
$first->setWord("Banana");

// the test will still pass, because it's a singleton.
var_dump($first->getWord() === $second->getWord()); // bool(true)