Simple helper function that makes it easier to understand:<?phpfunction createLazyGhost( string $class, ?callable $initializer = null, ?array $propertySetterCallables = null): object { $reflection = new ReflectionClass($class); return $reflection->newLazyGhost(function (object $object) use ($initializer, $propertySetterCallables) { // Initialize via the main initializer if provided if ($initializer) { $initializer($object); } // Set properties using the callables if provided if ($propertySetterCallables) { foreach ($propertySetterCallables as $property => $callable) { if (is_callable($callable)) { $object->$property = $callable(); } } } });}?>This supports using either a main object initializer and/or property initializers.Here's an example, where generating order IDs and calculating totals is considered expensive, so we only do it when necessary:<?phpclass Order { public string $orderId = ''; public float $total = 0.0;}$initializer = function (Order $order) { $order->orderId = 'ORD12345';};$propertySetters = [ 'total' => fn() => 200.75,];// Lazy ghost with both an initializer and property callables$lazyOrder = createLazyGhost(Order::class, $initializer, $propertySetters);// We can now use $lazyOrder as normal, even though the properties haven't been calculated yet.// Do something that triggers initializationecho $lazyOrder->orderId . PHP_EOL;echo $lazyOrder->total . PHP_EOL;?>