Serialize associative arrays (maps) as objects instead of arrays #87
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This implementation introduces the ability to serialize associative arrays as objects based on the added configuration. It determines whether an array is associative by analyzing doc-comment annotations.
Doc-comments are used since they provide the most consistent type information about array types. Empty arrays cannot be analyzed at runtime to determine whether they represent lists or maps, since they are identical in structure regardless of their intended type.
For promoted properties, type information is extracted from the
@param
type hint in the constructor doc-comment, for class properties from the@var
type hint in the property doc-comment, and for methods from the@return
type hint in the method doc-comment.Pre-assignment array transformation
Arrays are cast immediately before property assignment. This cannot be done in the
SerializeArrayItems
property serializer because it lacks access to the extractedPropertyType
information.Since identifying associative arrays by analyzing doc-comment type hints requires reflection, which compromises performance, handling this within the
SerializeArrayItems
property serializer would be suboptimal given that property serializers are called directly by the optimized object mapper.Recursive processing
The casting of associative arrays does not apply recursively, meaning the format of nested associative arrays remains unchanged. This behavior is reasonable from a serialization standpoint, as associative arrays should be handled as unstructured objects where no guarantees can be provided about their nested elements.
From a hydration perspective, this behavior is compatible with existing functionality. The format of nested associative arrays within parent associative arrays also remains unchanged.
Limitations
Values are cast to objects regardless of applied property serializers. This approach is reasonable given that associative arrays are unlikely to be represented as types other than (associative) arrays or objects, and property serializers are unlikely to deviate from this representation. Furthermore, when
serializeMapsAsObjects
is explicitly enabled, the consistent object casting aligns with the intended configuration.Backward compatibility
This implementation introduces a breaking change by adding the
typeFromProperty()
andtypeFromMethod()
methods to thePropertyTypeResolver
interface. Since this interface is not marked as@internal
, adding new methods constitutes a BC break for any existing implementations of this interface.Associative arrays are not cast to objects by default, so no behavioral breaking changes are introduced and existing serialization behavior is preserved.
Documentation: #serializing-maps-as-objects