A PHP 8.4 property hook on a datetime calculation

Replacing virtual getter methods with PHP 8.4 property hooks makes data transfer objects and read models remarkably expressive. The trap is placing a dynamic instantiation inside a hook without realizing how often reading code evaluates it.

final readonly class SubscriptionPlan
{
    public function __construct(
        public string $name,
        public DateTimeImmutable $expiresAt
    ) {}

    // A property hook evaluating current time on every single read:
    public bool $isExpired {
        get => $this->expiresAt < new DateTimeImmutable();
    }
}

When filtering a list of four thousand user subscriptions in memory, sorting by $plan->isExpired instantiated four thousand DateTimeImmutable objects in fifteen milliseconds. Caching the reference timestamp before the loop or storing an integer unix timestamp directly dropped CPU time from 18ms to 0.4ms. Property hooks hide method call syntax, but they never hide runtime cost.