Singleton, Stopwatch and global functions
This page covers three small but widely used pieces of Foundation: the Singleton registry, the Stopwatch timing helper, and the global functions defined in the Raxos\Foundation namespace.
Singleton
Raxos\Foundation\Util\Singleton is a static registry that keeps at most one instance per class name. It is intentionally minimal: there is no dependency injection, only a shared map of class name to instance.
<?php
declare(strict_types=1);
use Raxos\Foundation\Util\Singleton;
$service = Singleton::get(MyService::class); // create on first call, reuse after
Singleton::has(MyService::class); // true
Singleton::getOrNull(MyService::class); // instance or null
// force a fresh instance with a plain constructor call
$fresh = Singleton::make(MyService::class);
// create with a factory when the constructor needs arguments
$service = Singleton::register(MyService::class, static fn() => new MyService($config));get()returns the existing instance or creates one with a plainnew $class()call.getOrNull()returns the existing instance ornullif none exists yet.has()reports whether an instance exists.make()always creates and stores a new instance.register()returns the existing instance or creates one using the given factory callable.
The singleton() function
The global singleton() function is a shorthand over the class. It returns an existing instance, or creates one with make() when no factory is given, or with register() when a factory is supplied. The Option type uses it internally so that Option::none() always returns the same shared None.
<?php
declare(strict_types=1);
use function Raxos\Foundation\singleton;
$service = singleton(MyService::class);
$service = singleton(MyService::class, static fn() => new MyService($config));Stopwatch
Raxos\Foundation\Util\Stopwatch is a high resolution timer built on hrtime. It measures the time between a start() and a stop(), and reports the result in a chosen unit.
<?php
declare(strict_types=1);
use Raxos\Foundation\Util\Stopwatch;
use Raxos\Foundation\Util\StopwatchUnit;
$stopwatch = new Stopwatch('Import');
$stopwatch->start();
// ... work ...
$stopwatch->stop();
$stopwatch->as(StopwatchUnit::MILLISECONDS); // float, or null when not stopped
$stopwatch->format(StopwatchUnit::MILLISECONDS); // e.g. '12.5ms'run() wraps a callable with a start and stop and returns the callable's result:
$result = $stopwatch->run(static fn() => importEverything());The static Stopwatch::measure() runs a callable, writes the elapsed time into a reference parameter, and returns the callable's result:
<?php
declare(strict_types=1);
use Raxos\Foundation\Util\Stopwatch;
use Raxos\Foundation\Util\StopwatchUnit;
$elapsed = 0.0;
$result = Stopwatch::measure($elapsed, static fn() => compute(), StopwatchUnit::MILLISECONDS);
// $elapsed now holds the running time in millisecondsSupporting enums
StopwatchStatehas the casesIDLE,RUNNINGandSTOPPED.StopwatchUnithas the casesNANOSECONDS,MICROSECONDS,MILLISECONDSandSECONDS.
See the Stopwatch API reference for full method signatures.
Global functions
The Raxos\Foundation namespace defines a handful of process and environment helpers, autoloaded through Composer.
<?php
declare(strict_types=1);
use function Raxos\Foundation\{env, isBuiltInServer, isCommandLineInterface, isTesting};
env('APP_NAME', 'Raxos'); // read an environment variable with a default
env('DEBUG', false); // when the default is a bool, the value is coerced to bool
env('WORKERS', 4); // when the default is an int, the value is coerced to int
isCommandLineInterface(); // true under the cli SAPI
isBuiltInServer(); // true under the cli-server SAPI
isTesting(); // reads the TESTING environment variableenv() returns the default when the variable is unset. When the default is an int the result is cast to an integer, and when it is a bool the values 1, true, yes and on are treated as true.