Symfony / Doctrine反序列化时间

我在Doctrine实体中创建了以下字段:

/**
 * @ORM\Column(type="time")
 * @Groups({"default"})
 */
private $timeFrom;

我正在尝试使用以下代码反序列化我的实体:

$workingDays = $serializer->deserialize($json, WorkingDay::class, 'json', array('groups' => array('default')));

我已尝试过几种来自javascript的时间/日期时间格式,但Symfony似乎没有对它们进行反序列化.

我的问题是:Symfony想要什么类型的格式作为反序列化到时间的输入?

最佳答案 通过Serializer的文档的外观,您需要在实例化$serializer实例时包含DateTimeNormalizer(
link).

$normalizers = [
    ...,
    new DateTimeNormalizer(),
];

$serializer = new Serializer(normalizers, [new JsonEncoder()]);

然后,使用您问题中的行.从理论上讲,它应该有效,但当时我无法测试它.你可以做到吗?

DateTimeNormalizer使用RFC3339格式,根据它,这是格式正确的值的示例:1985-04-12T23:20:50.52Z

更新:

为了使其工作,如上所述,您需要在序列化程序的规范化器列表中包含DateTimeNormalizer.然而,这是它变得棘手的地方.

>规范化器的顺序很重要:

你必须先放置DateTimeNormalizer,否则,你会得到时髦的误导性MissingConstructorArgumentsException.

>类型发现

Serializer需要知道如何将字符串非规范化为DateTime.为此,ObjectNormalizer有一个类型提取器,用于查找有关底层类型的更多信息.可以通过多种方式发现类型,但我假设您将通过PhpDocExtractorDoctrineExtractor完成.

现在,例子:

// Prepare the data in form of JSON string
$incomingData = [
    'id' => 1337,
    'time' => '2018-07-24T01:29:50.00Z',
    'info' => 'Lorem ipsum'
];
$rawData = json_encode($incomingData);


$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));

// Very important to set type extractor
$normalizer = new ObjectNormalizer($classMetadataFactory, null, null, new PhpDocExtractor());

$normalizers = [
    new DateTimeNormalizer(),
    $normalizer,
];

$serializer = new Serializer($normalizers, [new JsonEncoder()]);

$myObject = $serializer->deserialize($rawData, FooObject::class, 'json');

var_dump($myObject);

这产生了:

object(App\Data\FooObject)[3333]
  private 'id' => int 1337
  private 'time' => 
    object(DateTime)[3540]
      public 'date' => string '2018-04-12 23:20:50.520000' (length=26)
      public 'timezone_type' => int 2
      public 'timezone' => string 'Z' (length=1)
  private 'info' => string 'Lorem ipsum' (length=11)

希望这可以帮助…

点赞