JMS序列化程序 - 为什么新对象没有通过构造函数实例化

mr1*_*086 7 php symfony doctrine-orm jmsserializerbundle

为什么除了json中的数据之外的所有值都使用null实例化新实体,为什么实体构造函数没有设置默认值 - 在构造函数中放置die()永远不会被执行.

更新:

好的,深入研究代码,当没有找到托管实体时,JMSS将使用doctrine instantiator类创建实体 - 它唯一的工作,创建实体而不调用构造函数.是否有一个原因?这是在里面JMS\Serializer\Construction\UnserializeObjectConstructor


我已经将对象构造函数配置为使用JMS编写的doctrine对象构造函数,但是同样的问题在有和没有这个的情况下发生.

jms_serializer.object_constructor:
    alias: jms_serializer.doctrine_object_constructor
    public: false
Run Code Online (Sandbox Code Playgroud)

现有实体更新没有问题,但是新实体缺少所有构造函数集默认值.

在'fields'元素0存在下,元素1是新的.

array (size=3)
  'id' => int 2
  'name' => string 'Categories' (length=10)
  'fields' => 
    array (size=2)
      0 => 
        array (size=7)
          'id' => int 49
          'displayName' => string 'Car Branded' (length=11)
          'type' => string 'checkboxlist' (length=12)
          'required' => boolean false
          'disabled' => boolean false
          'name' => string 'h49' (length=3)
      1 => 
        array (size=3)
          'type' => string 'email' (length=5)
          'name' => string 'field3491' (length=9)
          'displayName' => string 'Email' (length=5)
Run Code Online (Sandbox Code Playgroud)

反序列化后,实体看起来像这样:

object(stdClass)[2000]
  public '__CLASS__' => string 'AppBundle\Entity\FormElement' (length=28)
  public 'id' => null
  public 'label' => string 'Email' (length=5)
  public 'type' => string 'email' (length=5)
  public 'defaultValue' => null
  public 'required' => null
  public 'mappedField' => null
  public 'garbageCollection' => null
  public 'sortOrder' => null
  public 'disabled' => null
  public 'uuid' => null
  public 'form' => null
  public 'multiOptions' => null
  public 'filters' => null
  public 'submissions' => null
Run Code Online (Sandbox Code Playgroud)

实体构造函数:

public function __construct()
{
    $this->required = false;
    $this->disabled = false;
    $this->garbageCollection = false;
    $this->sortOrder = 0;
    $this->type = 'text';
}
Run Code Online (Sandbox Code Playgroud)

最后,这是如何反序列化:

$serializer = $this->get('jms_serializer');

$entryForm = $serializer->deserialize($json_data, 'AppBundle\Entity\EntryForm', 'json');
Run Code Online (Sandbox Code Playgroud)

mlo*_*erg 8

问题是默认的ObjectConstructor使用Doctrine的Instantiator,它不会调用类的构造函数.要解决此问题,您可以创建自己的ObjectConstructor,它只返回类的新实例.

例:

<?php

namespace AppBundle\Serializer;

use JMS\Serializer\Construction\ObjectConstructorInterface;
use JMS\Serializer\DeserializationContext;
use JMS\Serializer\Metadata\ClassMetadata;
use JMS\Serializer\VisitorInterface;

class ObjectConstructor implements ObjectConstructorInterface
{
    /**
     * {@inheritdoc}
     */
    public function construct(
        VisitorInterface $visitor,
        ClassMetadata $metadata,
        $data,
        array $type,
        DeserializationContext $context
    ) {
        $className = $metadata->name;

        return new $className();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您正在使用该捆绑包,只需将jms_serializer.unserialize_object_constructor.class参数设置为该新类.否则,在构建器中,使用该类作为对象构造函数.