-
-
Notifications
You must be signed in to change notification settings - Fork 586
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Serialization of DateTimeInterfaces #1342
Comments
which version of the serialization library are you using? can you please provide a failing test case? |
Hi, I'm using php 8.0.9 with JMS 3.14.0 & Chronos 2.2.0 Simple code to reproduce: <?php
use JMS\Serializer\Annotation as JMS;
use Cake\Chronos\Chronos;
use DateTimeInterface;
require_once('./vendor/autoload.php');
class SerializeDate
{
/**
* @var DateTimeInterface
* @JMS\Type("DateTimeInterface<'Y-m-d'>")
* @JMS\SerializedName("birthdate")
*/
public $dateTime;
}
$sendData = new SerializeDate();
$sendData->dateTime = Chronos::now();
$build = \JMS\Serializer\SerializerBuilder::create()->build();
print_r($build->serialize($sendData, 'json')); |
I suspect the problem is in Reporoducer without external library: <?php
require __DIR__ . '/vendor/autoload.php';
$serializer = JMS\Serializer\SerializerBuilder::create()->build();
class CustomDateTimeImmutable extends DateTimeImmutable
{
private $foo = 123;
}
$customDateTime = new CustomDateTimeImmutable();
echo $serializer->serialize(['time' => $customDateTime], 'json'); // {"time":{"foo":123}} |
Handlers are organised in an array based on the type. The type gets passed to the Similar for deserializing, you can ask for the interface but this will only result in DateTime object (handler points to deserializeDateTimeFrom (either Yaml or Json, which produce the mutable DateTime). @goetas @Majkl578 Perhaps a solution limited to DateTimeInterface where implemented interfaces could be loaded by reflection and then treat the target as a plain DateTime ? |
I think that this line (https://github.com/schmittjoh/serializer/blob/master/src/GraphNavigator/SerializationGraphNavigator.php#L188) is the suspect. it changes the type at runtime... |
It does, but at the same time it looks like that's what it needs to do. It correctly finds that a custom implementation of DatetimeInterface is a subclass of DateTimeInterface and then replaces the type (initially DateTimeInterface) with the concrete class. If I remove that check and the $type['name'] remains the interface, the resulting item is empty (as there's no handler for DateTimeInterface). However, if I make the I wonder though about the reason for changing the type at runtime? It might make sense to check the concrete type if there's no handler for the superclass (which, incidentally, it's also the case for DateTimeInterface). After doing this I see that the nested interfaces tests fail, since there's no handler for the interface. Maybe it makes sense to add a check, if there's a handler for the current type (aka interface) then don't switch ? |
Hi @goetas I'm wondering if there's anything else I can do for the merge request to have it approved and accepted? Is the solution ok? Thanks |
fixed in #1344 |
Steps required to reproduce the problem
sample code
Expected Result
Actual Result
Chronos objects implement DateTimeInterface so I believe they should be serialised accordingly.
If I use a regular DateTime (that also implements DateTimeInterface), the result is as expected.
The behaviour is at the very least inconsistent:
Cheers!
The text was updated successfully, but these errors were encountered: