Closed mpragliola closed 5 months ago
Hi @mpragliola ! Is it the same issue as in https://github.com/schmittjoh/serializer/issues/1367 ?
@scyzoryck no, I don't think so. In #1367 the property that causes the error has no default value and the class has no constructor, while in my case there is clearly a null
assigned as default, but as promoted property.
And, if i demote the property and assign the default outside the constructor, the error disappears, which is logical given the constructor is completely skipped by JMSSerializer in this case.
Same problem here with Collection
, even worst because I cannot initialize it:
#[ORM\OneToMany(mappedBy: 'cart', targetEntity: CartItem::class)]
#[Serializer\Accessor(setter: 'setItems')]
private Collection $items;
public function __construct()
{
$this->items = new ArrayCollection();
}
The core issue at hand is that the default values of PHP constructor arguments are just that - yes, even if it's defined as the promoted property - only the property type and name definition is promoted to class level, not the default value, because technically it's a constructor default value. (Honestly I hope this will change in future PHP)
However PHP does provide ways how to check:
So it certainly is implementable and would be appreciated by many, myself included. It makes absolutely no sense to me that for serialization you can define (not)serializing null behavior, but not for deserialization. :shrug:
Option 2 is to simply provide e.g. a PHP attribute to define default values for deserialization.
Hi all!
I created a wrapper for JMS Serializer (a temporary solution till JMS supports promoted props) which
deserializeWithoutValidation()
/fromArrayWithoutValidation()
)DeserializationException
)Serializer implements JMS\Serializer\ArrayTransformerInterface
and JMS\Serializer\SerializerInterface
interfaces.
The code is compliant with PHPStan level 8.
It was written in Symfony 6.4 and it should work in Symfony 7.x however, it should be easily adaptable to other frameworks.
Check out the implementation: https://gist.github.com/iKsSs/f048fd04f28c638a5c3d8b4390976d25
Coming back to this issue.
@mpragliola Are you using DefaultValuePropertyDriver
? The case that you are describing in the first post seems to be working fine for me. See BaseSerializationTestCase::testConstructorPromotionWithDefaultValues
test case that is covering exactly what you described :)
We experienced the same problem when using the JSM Serializer Bundle with Symfony Framework.
Adding the following config solved the issue for us.
jms_serializer:
default_value_property_reader_support: true
We experienced the same problem when using the JSM Serializer Bundle with Symfony Framework.
Adding the following config solved the issue for us.
jms_serializer: default_value_property_reader_support: true
@markuspoerschke this indeed fixes our issue :blush: Thanks! @mpragliola let's close here
PHP version: 8.1.15 JMS Serializer version: 3.22.0
When I try to deserialize some payload into a class with promoted properties and a default value, I get an error when I try to use missing properties, despite having default values set in the constructor.
Steps required to reproduce the problem
Expected Result
Actual Result
Possible root cause
As far as I've seen, the target class is instantiated via reflection but without using the constructor itself (
Instantiator.php
):This would leave those properties in an uninitialized state.
Workaround
I have to explicitly initialize and demote the properties: