Lazy Objects in PHP 8.4: A New Era of Efficient Object Handling

itsimiro
2 min readJust now

--

PHP 8.4 introduces lazy objects, a feature designed to defer an object's initialization until it is accessed. This approach minimizes resource usage, especially for objects with heavy initialization logic that may only sometimes be used during execution.

What is the difference between a default object and a lazy one?

Lazy objects use a dynamically created proxy object to defer the execution of the target object’s constructor. Reflection is the key to making this proxy, which mimics the original class, allowing the actual object to remain uninitialized until it is accessed.

<?php

class MyClass
{
public function __construct(private int $foo)
{
echo 'Accessing a method triggers initialization'.PHP_EOL;
}

public function getFoo(): int
{
return $this->foo;
}
}

$object = new MyClass(1);

echo 'lazy object created'.PHP_EOL;
echo 'call lazy object '. $object->getFoo(). PHP_EOL;

Output:

Accessing a method triggers initialization
lazy object created
call lazy object 1

In this example, when an object is created, the MyClass constructor is immediately called, which displays “Access to a method triggers initialization”. The class has a private property $foo that is initialized at runtime.

Use a Lazy Object:

<?php

class MyClass
{
public function __construct(private int $foo)
{
echo 'Accessing a method triggers initialization'.PHP_EOL;
}

public function getFoo(): int
{
return $this->foo;
}
}

$initializer = static function (MyClass $ghost): void {
$ghost->__construct(123);
};

$reflector = new ReflectionClass(MyClass::class);
$object = $reflector->newLazyGhost($initializer);

echo 'lazy object created'.PHP_EOL;
echo 'call lazy object '. $object->getFoo(). PHP_EOL;

Output:

lazy object created
Accessing a method triggers initialization
call lazy object 123

In this code, the newLazyGhost method creates a lazy object. The initializer function is defined to initialize the object only when the method is called. The ReflectionClass object is responsible for creating a proxy object that is not a full instance of MyClass before calling getFoo().

When getFoo() is called, the constructor is launched (which displays “Accessing a method triggers initialization”), and the object is initialized to 123, as shown in the output.

Advantages of Lazy Objects

Improved Performance:

Delayed instantiation reduces memory usage and improves performance, especially when objects are accessed conditionally.

Transparent Proxying:

Developers interact with lazy objects in the same way as with regular objects, without any additional efforts to work with proxies.

Optimized Resource Management:

Useful in scenarios such as dependency injection containers, ORM systems, or API integrations where initialization can be deferred until needed.

Limitations

Serialization:

Lazy objects can make serialization and deserialization difficult due to their deferred state.

Debugging Complexity:

Stack traces can include proxy layers, making debugging slightly more complex.

Conclusion

Lazy objects in PHP 8.4 are a powerful tool for improving performance and resource efficiency in modern applications. By deferring initialization until necessary, they provide a cleaner and more scalable approach to managing complex object lifecycles.

To learn more about lazy objects, visit the official PHP RFC page.

--

--

itsimiro
itsimiro

Written by itsimiro

Passionate developer exploring the realms of software engineering. Writing about tech, coding adventures, and everything in between!