@@ -207,169 +207,5 @@ pattern, which also works with abstract classes, internal classes, and interface
207
207
Use this mechanism only when native lazy objects cannot be leveraged
208
208
(otherwise you'll get a deprecation notice).
209
209
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
-
374
210
.. _`OPcache` : https://www.php.net/opcache
375
211
.. _`PSR-2` : https://www.php-fig.org/psr/psr-2/
0 commit comments