You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 5b87809
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: ChangeLog.md
+7Lines changed: 7 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,6 +2,12 @@
2
2
3
3
All notable changes are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.
4
4
5
+
## [8.3.0] - 2026-MM-DD
6
+
7
+
### Added
8
+
9
+
*[#202](https://github.com/sebastianbergmann/exporter/issues/202): `ObjectReferenceExporter` interface that an object exporter can implement to provide the representation of the reference that replaces an object it handles when that object is (indirectly) nested in itself
10
+
5
11
## [8.2.1] - 2026-08-07
6
12
7
13
### Fixed
@@ -75,6 +81,7 @@ All notable changes are documented in this file using the [Keep a CHANGELOG](htt
75
81
76
82
* This component is no longer supported on PHP 8.2
Copy file name to clipboardExpand all lines: README.md
+73-2Lines changed: 73 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -279,7 +279,7 @@ Array &0 [
279
279
print $exporter->export([$money, $money]);
280
280
```
281
281
282
-
The exception is an object that is (indirectly) nested in itself: it cannot be exported this way without recursing infinitely and is replaced with a reference to the object.
282
+
The exception is an object that is (indirectly) nested in itself: it cannot be exported this way without recursing infinitely and is replaced with a reference to the object (see [Objects Nested in Themselves](#objects-nested-in-themselves)).
283
283
284
284
### Exporting Nested Values
285
285
@@ -319,6 +319,77 @@ Array &0 [
319
319
print $exporter->export(['basket' => new Basket([new Money(1999, 'EUR')])]);
320
320
```
321
321
322
+
### Objects Nested in Themselves
323
+
324
+
An object that is (indirectly) nested in itself cannot be exported by an object exporter without recursing infinitely. When such an object occurs again while it is being exported by an object exporter, it is replaced with a reference to the object:
325
+
326
+
```php
327
+
/*
328
+
Person (Alice) Array &0 [
329
+
0 => Person (Bob) Array &1 [
330
+
0 => Person Object #2,
331
+
],
332
+
]
333
+
*/
334
+
335
+
$alice = new Person('Alice');
336
+
$bob = new Person('Bob');
337
+
338
+
$alice->befriend($bob);
339
+
340
+
print $exporter->export($alice);
341
+
```
342
+
343
+
An object exporter can provide the representation of this reference by also implementing the `ObjectReferenceExporter` interface. When its `exportReference()` method returns `null`, the default representation of the reference is used:
344
+
345
+
```php
346
+
<?php declare(strict_types=1);
347
+
use SebastianBergmann\Exporter\ExportContext;
348
+
use SebastianBergmann\Exporter\Exporter;
349
+
use SebastianBergmann\Exporter\ObjectExporter;
350
+
use SebastianBergmann\Exporter\ObjectReferenceExporter;
351
+
352
+
final class PersonExporter implements ObjectExporter, ObjectReferenceExporter
353
+
{
354
+
public function handles(object $object): bool
355
+
{
356
+
return $object instanceof Person;
357
+
}
358
+
359
+
public function export(object $object, Exporter $exporter, int $indentation, ExportContext $context): string
public function exportReference(object $object): ?string
371
+
{
372
+
assert($object instanceof Person);
373
+
374
+
return sprintf('Person (%s)', $object->name());
375
+
}
376
+
}
377
+
```
378
+
379
+
```php
380
+
/*
381
+
Person (Alice) Array &0 [
382
+
0 => Person (Bob) Array &1 [
383
+
0 => Person (Alice),
384
+
],
385
+
]
386
+
*/
387
+
388
+
print $exporter->export($alice);
389
+
```
390
+
391
+
The object exporter is only asked for the representation of the reference, it is not given the opportunity to export the object again. When object exporters are composed into an `ObjectExporterChain`, the reference is provided by the object exporter that exports the object, which is the first one whose `handles()` method returns `true`.
392
+
322
393
### Compact Exports
323
394
324
395
`Exporter::shortenedExport()` and `Exporter::shortenedRecursiveExport()` consult object exporters as well. The representation an object exporter provides is collapsed to a single line and shortened when it is longer than the configured maximum length:
Bear in mind that an object that is (indirectly) nested in itself is replaced with a reference to the object instead of being exported by an object exporter again.
426
+
Bear in mind that an object that is (indirectly) nested in itself is replaced with a reference to the object instead of being exported by an object exporter again. An object exporter that implements `ObjectReferenceExporter` can provide the representation of this reference.
0 commit comments