Factories and Anonymous

Static Factories and Anonymous Classes

Alternative ways to build an object are static factories (named constructors) such as Money::fromString(); a private constructor forces callers through them. An anonymous class (PHP 7.0, readonly since 8.3) declares and instantiates a one-off class, ideal as a test double.

A named constructor behind a private constructor, and an anonymous test clockPHP
<?php
final class Money {
  private function __construct(
    public private(set) int $cents, public private(set) string $cur) {}
  public static function fromString(string $s): self {        // "12.50 EUR"
    [$units, $hundredths, $cur] = sscanf($s, '%d.%2d %3s');
    return new self($units * 100 + $hundredths, $cur);
  }
}
interface Clock { public function now(): DateTimeImmutable; }
$clock = new class('2026-09-23 10:00') implements Clock {
  public function __construct(private string $at) {}
  public function now(): DateTimeImmutable { return new DateTimeImmutable($this->at); }
};
$m = Money::fromString('12.50 EUR');
echo "$m->cents $m->cur | ", $clock->now()->format('D H:i'), "\n";
echo strstr(get_class($clock), "\0", true), "\n";   // the name up to its NUL byte
try { new Money(1, 'USD'); } catch (Error $e) { echo $e->getMessage(), "\n"; }
Output
1250 EUR | Wed 10:00
Clock@anonymous
Call to private Money::__construct() from global scope

The generated name continues after the NUL byte with the file, line and a counter, so never store it. Return static from factories that subclasses should inherit (Subsection 4.9.6).