Symfony/Doctrine 反序列化时间

Maj*_*eit 5 time serialization doctrine symfony

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

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

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

$workingDays = $serializer->deserialize($json, WorkingDay::class, 'json', array('groups' => array('default')));
Run Code Online (Sandbox Code Playgroud)

我已经尝试了几种来自 javascript 的时间/日期时间格式,但 Symfony 似乎没有反序列化它们。

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

Jov*_*vic 3

从 Serializer 的文档来看,实例化实例时需要包含DateTimeNormalizer( link ) $serializer

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

$serializer = new Serializer(normalizers, [new JsonEncoder()]);
Run Code Online (Sandbox Code Playgroud)

然后,使用您问题中的那句话。理论上,它应该有效,但目前我无法测试它。你可以做到吗?

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

更新:

为了使其工作,正如我上面假设的那样,您需要将其包含DateTimeNormalizer在序列化器的规范化器列表中。然而,这就是棘手的地方。

  1. 标准化器的顺序很重要:

你必须把它放在第一位DateTimeNormalizer,否则,你会被误导MissingConstructorArgumentsException

  1. 类型发现

序列化器需要知道如何string非规范化为DateTime. 为此,ObjectNormalizer有一个类型提取器,用于查找有关基础类型的更多信息。可以通过多种方式发现类型,但我假设您将通过PhpDocExtractor或完成DoctrineExtractor

现在,例子:

// 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);
Run Code Online (Sandbox Code Playgroud)

这产生了:

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)
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助...