@@ -137,9 +137,9 @@ to use in order of priority:
137137
138138``` php
139139(new SerializerBuilder())
140- ->addMapperLast(new TestMapper()) // then this one
141- ->addFactoryLast(new TestFactory()) // and this one last
142- ->addFactory(new TestFactory()) // attempted first
140+ ->addMapperLast(new TestMapper()) // #2 - then this one
141+ ->addFactoryLast(new TestFactory()) // #3 - and this one last
142+ ->addFactory(new TestFactory()) // #1 - attempted first
143143```
144144
145145A factory has the following signature:
@@ -205,11 +205,11 @@ methods: `serialize` and `deserialize`. They do exactly what they're called.
205205
206206## Naming of keys
207207
208- By default serializer preserves the naming of keys, but this is easily customizable (in order of priority):
208+ By default, serializer preserves the naming of keys, but this is easily customizable (in order of priority):
209209
210210- specify a custom property name using the ` #[SerializedName] ` attribute
211211- specify a custom naming strategy per class using the ` #[SerializedName] ` attribute
212- - specify a custom global naming strategy (use one of the built in or write your own)
212+ - specify a custom global (default) naming strategy (use one of the built- in or write your own)
213213
214214Here's an example:
215215
@@ -235,7 +235,7 @@ class Item2 {
235235```
236236
237237Out of the box, strategies for ` snake_case ` , ` camelCase ` and ` PascalCase ` are provided,
238- but you it's trivial to implement your own:
238+ but it's trivial to implement your own:
239239
240240``` php
241241class PrefixedNaming implements NamingStrategy {
@@ -255,7 +255,7 @@ class SiftTrackData {}
255255
256256## Required, nullable, optional and default values
257257
258- By default if a property is missing in serialized payload:
258+ By default, if a property is missing in serialized payload:
259259
260260- nullable properties are just set to null
261261- properties with a default value - use the default value
@@ -319,6 +319,51 @@ $adapter->serialize(
319319);
320320```
321321
322+ ## Use default value for unexpected
323+
324+ There are situations where you're deserializing data from a third party that doesn't have an API documentation
325+ or one that can't keep a backwards compatibility promise. One such case is when a third party uses an enum
326+ and you expect that new enum values might get added in the future by them. For example, imagine this structure:
327+
328+ ``` php
329+ enum CardType: string
330+ {
331+ case CLUBS = 'clubs';
332+ case DIAMONDS = 'diamonds';
333+ case HEARTS = 'hearts';
334+ case SPADES = 'spades';
335+ }
336+
337+ readonly class Card {
338+ public function __construct(
339+ public CardType $type,
340+ public string $value,
341+ ) {}
342+ }
343+ ```
344+
345+ If you get an unexpected value for ` type ` , you'll get an exception:
346+
347+ ``` php
348+ // UnexpectedEnumValueException: Expected one of [clubs, diamonds, hearts, spades], but got 'joker'
349+ $adapter->deserialize('{"type": "joker"}');
350+ ```
351+
352+ So if you suspect that might happen, add a default value you wish to use (anything) and
353+ a ` #[UseDefaultForUnexpected] ` attribute:
354+
355+ ``` php
356+ readonly class Card {
357+ public function __construct(
358+ #[UseDefaultForUnexpected]
359+ public CardType $type = null,
360+ // Can be any other valid default value
361+ #[UseDefaultForUnexpected]
362+ public CardType $type2 = CardType::SPADES,
363+ ) {}
364+ }
365+ ```
366+
322367## Error handling
323368
324369This is expected to be used with client-provided data, so good error descriptions is a must.
@@ -369,9 +414,9 @@ There are some alternatives to this, but all of them will lack at least one of t
369414
370415- doesn't rely on inheritance, hence allows serializing third-party classes
371416- parses existing PHPDoc information instead of duplicating it through attributes
372- - supports generic types which are extremely useful for wrapper types
417+ - supports generic types which are quite useful for wrapper types
373418- allows simple extension through mappers and complex stuff through type adapters
374419- produces developer-friendly error messages for invalid data
375- - correctly handles optional (missing keys) and ` null ` values as separate concepts
420+ - correctly handles optional (missing keys) and ` null ` values as separate concerns
376421- simple to extend with additional formats
377- - simple internal structure: no node tree, no value wrappers, no PHP parsing, no inherent limitations
422+ - simple internal structure: no node tree, no value/JSON wrappers, no custom reflection / PHP parsing, no inherent limitations
0 commit comments