Skip to content

Update doc about lazy objects #20955

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions components/var_exporter.rst
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,34 @@ populated by using the special ``"\0"`` property name to define their internal v
"\0" => [$inputArray],
]);

Creating Lazy Objects
---------------------
Creating Lazy Objects on PHP ≥ 8.4
----------------------------------

Since version 8.4, PHP provides support for lazy objects via the reflection API.
This native API works with concrete classes. It doesn't with abstracts nor with
internal ones.

This components provides helpers to generate lazy objects using the decorator
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be component (without s), shouldn't it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, fixed while merging. Thanks!

pattern, which works with abstract or internal classes and with interfaces::

$proxyCode = ProxyHelper::generateLazyProxy(new \ReflectionClass(SomeInterface::class));
// $proxyCode should be dumped into a file in production envs
eval('class ProxyDecorator'.$proxyCode);

$proxy = ProxyDecorator::createLazyProxy(initializer: function (): SomeInterface {
// [...] Use whatever heavy logic you need here
// to compute the $dependencies of the proxied class
$instance = new SomeHeavyClass(...$dependencies);
// [...] Call setters, etc. if needed

return $instance;
});

Use this mechanism only when native lazy objects cannot be leveraged
(or you'll get a deprecation notice.)

Creating Lazy Objects on PHP < 8.3
----------------------------------

Lazy-objects are objects instantiated empty and populated on-demand. This is
particularly useful when you have for example properties in your classes that
Expand All @@ -193,6 +219,12 @@ you implement such mechanism easily in your classes.
LazyGhostTrait
~~~~~~~~~~~~~~

.. deprecated:: 7.3

``LazyGhostTrait`` is deprecated since Symfony 7.3; use PHP 8.4's native lazy
objects instead (note that using the trait with PHP < 8.4 triggers no deprecation
to help with the transition.)

Ghost objects are empty objects, which see their properties populated the first
time any method is called. Thanks to :class:`Symfony\\Component\\VarExporter\\LazyGhostTrait`,
the implementation of the lazy mechanism is eased. The ``MyLazyObject::populateHash()``
Expand Down Expand Up @@ -273,6 +305,12 @@ of :ref:`Virtual Proxies <var-exporter_virtual-proxies>`.
LazyProxyTrait
~~~~~~~~~~~~~~

.. deprecated:: 7.3

``LazyProxyTrait`` is deprecated since Symfony 7.3; use PHP 8.4's native lazy
objects instead (note that using the trait with PHP < 8.4 triggers no deprecation
to help with the transition.)

The purpose of virtual proxies in the same one as
:ref:`ghost objects <var-exporter_ghost-objects>`, but their internal behavior is
totally different. Where ghost objects requires to extend a base class, virtual
Expand Down
8 changes: 0 additions & 8 deletions service_container/lazy_services.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ until you interact with the proxy in some way.
Lazy services do not support `final`_ or ``readonly`` classes, but you can use
`Interface Proxifying`_ to work around this limitation.

In PHP versions prior to 8.0 lazy services do not support parameters with
default values for built-in PHP classes (e.g. ``PDO``).

.. _lazy-services_configuration:

Configuration
Expand Down Expand Up @@ -78,11 +75,6 @@ same signature of the class representing the service should be injected. A lazy
itself when being accessed for the first time). The same happens when calling
``Container::get()`` directly.

To check if your lazy service works you can check the interface of the received object::

dump(class_implements($service));
// the output should include "Symfony\Component\VarExporter\LazyObjectInterface"

You can also configure your service's laziness thanks to the
:class:`Symfony\\Component\\DependencyInjection\\Attribute\\Autoconfigure` attribute.
For example, to define your service as lazy use the following::
Expand Down