Accept any object exporter, not just a chain, in Exporter's constructor

This commit is contained in:
Sebastian Bergmann 2026-08-01 09:11:45 +02:00
parent b5aff00a52
commit 792150d027
No known key found for this signature in database
4 changed files with 36 additions and 12 deletions

View File

@ -6,7 +6,7 @@ All notable changes are documented in this file using the [Keep a CHANGELOG](htt
### Added ### Added
`ObjectExporter` interface, `ObjectExporterChain`, and `ExportContext` for customizing how objects are exported (a chain can be passed to `Exporter`'s constructor and is consulted before the default representation of an object is used) `ObjectExporter` interface, `ObjectExporterChain`, and `ExportContext` for customizing how objects are exported (an object exporter can be passed to `Exporter`'s constructor and is consulted before the default representation of an object is used)
## [8.1.1] - 2026-07-13 ## [8.1.1] - 2026-07-13

View File

@ -202,16 +202,13 @@ final class MoneyExporter implements ObjectExporter
} }
``` ```
Object exporters are registered by passing an `ObjectExporterChain` to `Exporter`'s constructor. They are consulted, in the order in which they are composed into the chain, before the default representation of an object is used. The first object exporter whose `handles()` method returns `true` is asked for the representation: An object exporter is registered by passing it to `Exporter`'s constructor. It is consulted before the default representation of an object is used:
```php ```php
<?php declare(strict_types=1); <?php declare(strict_types=1);
use SebastianBergmann\Exporter\Exporter; use SebastianBergmann\Exporter\Exporter;
use SebastianBergmann\Exporter\ObjectExporterChain;
$exporter = new Exporter( $exporter = new Exporter(objectExporter: new MoneyExporter);
objectExporter: new ObjectExporterChain([new MoneyExporter]),
);
// Money (1999 EUR) // Money (1999 EUR)
print $exporter->export(new Money(1999, 'EUR')); print $exporter->export(new Money(1999, 'EUR'));
@ -230,6 +227,23 @@ $price->gross = new Money(2379, 'EUR');
print $exporter->export($price); print $exporter->export($price);
``` ```
`ObjectExporterChain` composes multiple object exporters into a single one. They are consulted in the order in which they are composed into the chain and the first one whose `handles()` method returns `true` is asked for the representation:
```php
<?php declare(strict_types=1);
use SebastianBergmann\Exporter\Exporter;
use SebastianBergmann\Exporter\ObjectExporterChain;
$exporter = new Exporter(
objectExporter: new ObjectExporterChain(
[
new BasketExporter,
new MoneyExporter,
],
),
);
```
Enums are objects and are therefore passed to the object exporters as well. When no object exporter handles an object, the default representation is used for it. Enums are objects and are therefore passed to the object exporters as well. When no object exporter handles an object, the default representation is used for it.
### Repeated Occurrences ### Repeated Occurrences
@ -302,10 +316,6 @@ Array &0 [
] ]
*/ */
$exporter = new Exporter(
objectExporter: new ObjectExporterChain([new BasketExporter, new MoneyExporter]),
);
print $exporter->export(['basket' => new Basket([new Money(1999, 'EUR')])]); print $exporter->export(['basket' => new Basket([new Money(1999, 'EUR')])]);
``` ```

View File

@ -61,13 +61,13 @@ final readonly class Exporter
* @var positive-int * @var positive-int
*/ */
private int $maxLengthForStrings; private int $maxLengthForStrings;
private ?ObjectExporterChain $objectExporter; private ?ObjectExporter $objectExporter;
/** /**
* @param non-negative-int $shortenArraysLongerThan * @param non-negative-int $shortenArraysLongerThan
* @param positive-int $maxLengthForStrings * @param positive-int $maxLengthForStrings
*/ */
public function __construct(int $shortenArraysLongerThan = 0, int $maxLengthForStrings = 40, ?ObjectExporterChain $objectExporter = null) public function __construct(int $shortenArraysLongerThan = 0, int $maxLengthForStrings = 40, ?ObjectExporter $objectExporter = null)
{ {
$this->shortenArraysLongerThan = $shortenArraysLongerThan; $this->shortenArraysLongerThan = $shortenArraysLongerThan;
$this->maxLengthForStrings = $maxLengthForStrings; $this->maxLengthForStrings = $maxLengthForStrings;

View File

@ -670,6 +670,20 @@ EOF;
); );
} }
public function testObjectCanBeExportedByCustomObjectExporterThatIsNotComposedIntoChain(): void
{
$exporter = new Exporter(
0,
40,
new ObjectExporterThatHandlesEveryObject,
);
$this->assertSame(
'stdClass (indentation: 0)',
$exporter->export(new stdClass),
);
}
public function testObjectNestedInArrayCanBeExportedByCustomObjectExporter(): void public function testObjectNestedInArrayCanBeExportedByCustomObjectExporter(): void
{ {
$exporter = new Exporter( $exporter = new Exporter(