Simple helper function that makes it easier to understand:
<?php
function createLazyGhost(
string $class,
?callable $initializer = null,
?array $propertySetterCallables = null
): object {
$reflection = new ReflectionClass($class);
return $reflection->newLazyGhost(function (object $object) use ($initializer, $propertySetterCallables) {
if ($initializer) {
$initializer($object);
}
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:
<?php
class Order {
public string $orderId = '';
public float $total = 0.0;
}
$initializer = function (Order $order) {
$order->orderId = 'ORD12345';
};
$propertySetters = [
'total' => fn() => 200.75,
];
$lazyOrder = createLazyGhost(Order::class, $initializer, $propertySetters);
echo $lazyOrder->orderId . PHP_EOL;
echo $lazyOrder->total . PHP_EOL;
?>