Encodera

Thanks for reading!

Donate to the site — we work hard for you.

How to make a singleton

Short answer

Make the constructor private and hand out the single object from a static method:

<?php
 
class Config
{
    private static ?Config $instance = null;
 
    private function __construct(public readonly string $env) {}
 
    public static function get(): self
    {
        return self::$instance ??= new self('production');
    }
}
 
var_dump(Config::get() === Config::get());
echo Config::get()->env;

Output:

bool(true)
production

Why it is avoided

A singleton is a hidden global variable: a class calling Config::get() cannot be tested with other settings. Modern code creates the object once and passes it to the constructors of whoever needs it.

<?php
 
class Config
{
    public function __construct(public readonly string $env) {}
}
 
class Mailer
{
    public function __construct(private Config $config) {}
 
    public function mode(): string
    {
        return $this->config->env === 'production' ? 'real' : 'fake';
    }
}
 
echo (new Mailer(new Config('testing')))->mode();

Output:

fake

Functions used in this recipe

  • Closure — The class of anonymous functions and closures.
  • constant — Returns the value of a constant by its name in a string.
  • class_exists — Checks whether a class is defined.

Thanks for reading!

Donate to the site — we work hard for you.