Skip to content

Commit 13f488b

Browse files
committed
minor #21067 [VarExporter] Remove LazyGhostTrait and LazyProxyTrait in favor of native lazy objects (alamirault)
This PR was merged into the 8.0 branch. Discussion ---------- [VarExporter] Remove `LazyGhostTrait` and `LazyProxyTrait` in favor of native lazy objects Fix #21059 Side question: For 8.0 branch, what is the process for removing deprecations and versionadded ? Wait new issues from code repository and then remove remaining directives ? Commits ------- 5d6c3a8 [VarExporter] Remove LazyGhostTrait and LazyProxyTrait in favor of native lazy objects
2 parents cd79ed8 + 5d6c3a8 commit 13f488b

File tree

1 file changed

+0
-164
lines changed

1 file changed

+0
-164
lines changed

components/var_exporter.rst

Lines changed: 0 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -207,169 +207,5 @@ pattern, which also works with abstract classes, internal classes, and interface
207207
Use this mechanism only when native lazy objects cannot be leveraged
208208
(otherwise you'll get a deprecation notice).
209209

210-
Legacy Creation of Lazy Objects
211-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
212-
213-
When using a PHP version earlier than 8.4, native lazy objects are not available.
214-
In these cases, the VarExporter component provides two traits that help you
215-
implement lazy-loading mechanisms in your classes.
216-
217-
.. _var-exporter_ghost-objects:
218-
219-
LazyGhostTrait
220-
..............
221-
222-
.. deprecated:: 7.3
223-
224-
``LazyGhostTrait`` is deprecated since Symfony 7.3. Use PHP 8.4's native lazy
225-
objects instead. Note that using the trait with PHP versions earlier than 8.4
226-
does not trigger a deprecation, to ease the transition.
227-
228-
Ghost objects are empty objects, which see their properties populated the first
229-
time any method is called. Thanks to :class:`Symfony\\Component\\VarExporter\\LazyGhostTrait`,
230-
the implementation of the lazy mechanism is eased. The ``MyLazyObject::populateHash()``
231-
method will be called only when the object is actually used and needs to be
232-
initialized::
233-
234-
namespace App\Hash;
235-
236-
use Symfony\Component\VarExporter\LazyGhostTrait;
237-
238-
class HashProcessor
239-
{
240-
use LazyGhostTrait;
241-
242-
// This property may require a heavy computation to have its value
243-
public readonly string $hash;
244-
245-
public function __construct()
246-
{
247-
self::createLazyGhost(initializer: $this->populateHash(...), instance: $this);
248-
}
249-
250-
private function populateHash(array $data): void
251-
{
252-
// Compute $this->hash value with the passed data
253-
}
254-
}
255-
256-
:class:`Symfony\\Component\\VarExporter\\LazyGhostTrait` also allows to
257-
convert non-lazy classes to lazy ones::
258-
259-
namespace App\Hash;
260-
261-
use Symfony\Component\VarExporter\LazyGhostTrait;
262-
263-
class HashProcessor
264-
{
265-
public readonly string $hash;
266-
267-
public function __construct(array $data)
268-
{
269-
$this->populateHash($data);
270-
}
271-
272-
private function populateHash(array $data): void
273-
{
274-
// ...
275-
}
276-
277-
public function validateHash(): bool
278-
{
279-
// ...
280-
}
281-
}
282-
283-
class LazyHashProcessor extends HashProcessor
284-
{
285-
use LazyGhostTrait;
286-
}
287-
288-
$processor = LazyHashProcessor::createLazyGhost(initializer: function (HashProcessor $instance): void {
289-
// Do any operation you need here: call setters, getters, methods to validate the hash, etc.
290-
$data = /** Retrieve required data to compute the hash */;
291-
$instance->__construct(...$data);
292-
$instance->validateHash();
293-
});
294-
295-
While you never query ``$processor->hash`` value, heavy methods will never be
296-
triggered. But still, the ``$processor`` object exists and can be used in your
297-
code, passed to methods, functions, etc.
298-
299-
Ghost objects unfortunately can't work with abstract classes or internal PHP
300-
classes. Nevertheless, the VarExporter component covers this need with the help
301-
of :ref:`Virtual Proxies <var-exporter_virtual-proxies>`.
302-
303-
.. _var-exporter_virtual-proxies:
304-
305-
LazyProxyTrait
306-
..............
307-
308-
.. deprecated:: 7.3
309-
310-
``LazyProxyTrait`` is deprecated since Symfony 7.3. Use PHP 8.4's native lazy
311-
objects instead. Note that using the trait with PHP versions earlier than 8.4
312-
does not trigger a deprecation, to ease the transition.
313-
314-
The purpose of virtual proxies in the same one as
315-
:ref:`ghost objects <var-exporter_ghost-objects>`, but their internal behavior is
316-
totally different. Where ghost objects requires to extend a base class, virtual
317-
proxies take advantage of the **Liskov Substitution principle**. This principle
318-
describes that if two objects are implementing the same interface, you can swap
319-
between the different implementations without breaking your application. This is
320-
what virtual proxies take advantage of. To use virtual proxies, you may use
321-
:class:`Symfony\\Component\\VarExporter\\ProxyHelper` to generate proxy's class
322-
code::
323-
324-
namespace App\Hash;
325-
326-
use Symfony\Component\VarExporter\ProxyHelper;
327-
328-
interface ProcessorInterface
329-
{
330-
public function getHash(): bool;
331-
}
332-
333-
abstract class AbstractProcessor implements ProcessorInterface
334-
{
335-
protected string $hash;
336-
337-
public function getHash(): bool
338-
{
339-
return $this->hash;
340-
}
341-
}
342-
343-
class HashProcessor extends AbstractProcessor
344-
{
345-
public function __construct(array $data)
346-
{
347-
$this->populateHash($data);
348-
}
349-
350-
private function populateHash(array $data): void
351-
{
352-
// ...
353-
}
354-
}
355-
356-
$proxyCode = ProxyHelper::generateLazyProxy(new \ReflectionClass(AbstractProcessor::class));
357-
// $proxyCode contains the actual proxy and the reference to LazyProxyTrait.
358-
// In production env, this should be dumped into a file to avoid calling eval().
359-
eval('class HashProcessorProxy'.$proxyCode);
360-
361-
$processor = HashProcessorProxy::createLazyProxy(initializer: function (): ProcessorInterface {
362-
$data = /** Retrieve required data to compute the hash */;
363-
$instance = new HashProcessor(...$data);
364-
365-
// Do any operation you need here: call setters, getters, methods to validate the hash, etc.
366-
367-
return $instance;
368-
});
369-
370-
Just like ghost objects, while you never query ``$processor->hash``, its value
371-
will not be computed. The main difference with ghost objects is that this time,
372-
a proxy of an abstract class was created. This also works with internal PHP class.
373-
374210
.. _`OPcache`: https://www.php.net/opcache
375211
.. _`PSR-2`: https://www.php-fig.org/psr/psr-2/

0 commit comments

Comments
 (0)