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)
productionWhy 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:
fakeFunctions 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.