Symfony JMS序列化程序使用抽象父类反序列化
我有一个抽象的父(映射的超级)类,它有几个具有不同属性的子类,我想反序列化这些子类。 我使用MongoDB和Doctrine ODM存储数据,因此我还有一个鉴别器字段,告诉Doctrine使用了哪个子类(还有一个自定义的“type”属性ontop,在其他地方用于确定当前处理的类) 当反序列化我的模型时,我得到一个异常,告诉我不可能创建抽象类的实例(当然)-现在我想知道如何告诉JMS反序列化器应该使用哪个继承类(这就是为什么我使用自定义的Symfony JMS序列化程序使用抽象父类反序列化,symfony,deserialization,doctrine-odm,jmsserializerbundle,Symfony,Deserialization,Doctrine Odm,Jmsserializerbundle,我有一个抽象的父(映射的超级)类,它有几个具有不同属性的子类,我想反序列化这些子类。 我使用MongoDB和Doctrine ODM存储数据,因此我还有一个鉴别器字段,告诉Doctrine使用了哪个子类(还有一个自定义的“type”属性ontop,在其他地方用于确定当前处理的类) 当反序列化我的模型时,我得到一个异常,告诉我不可能创建抽象类的实例(当然)-现在我想知道如何告诉JMS反序列化器应该使用哪个继承类(这就是为什么我使用自定义的类型实例变量的原因,例如,因为我无法访问条令的鉴别器字段映射
类型
实例变量的原因,例如,因为我无法访问条令的鉴别器字段映射)
我可以成功地挂接到preDeserializeEvent
-因此可能会在那里进行一些切换/案例(或使用)
简而言之,我的模型(抽象类):
有什么想法吗?我在插件的Tests目录中找到了一个鉴别器映射,不幸的是,这还没有记录在案: 文件已更新
您应该将您的“更新”复制为anwser,并将此问题标记为anwsered-这样,其他可能有相同问题的人将清楚地看到,此页面上有一个有效的解决方案,试图使用此解决方案进行反序列化I get
LogicError
:“在输入数据中找不到基类“…”的“鉴别器字段名”。”.但是我不希望输入数据有这个字段。这个字段只是为了克服PHP的“类型系统”。
<?php
namespace VBCMS\Bundle\AdminBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use JMS\Serializer\Annotation as Serializer;
/**
* abstract Class Module
* @Serializer\AccessType("public_method")
* @MongoDB\MappedSuperclass
* @MongoDB\InheritanceType("SINGLE_COLLECTION")
* @MongoDB\DiscriminatorField(fieldName="_discriminator_field")
* @MongoDB\DiscriminatorMap({
* "module"="Module",
* "text_module"="TextModule",
* "menu_module"="MenuModule",
* "image_module"="ImageModule"
* })
*/
abstract class Module {
const TYPE_MODULE_TEXT = 'module.text';
const TYPE_MODULE_MENU = 'module.menu';
const TYPE_MODULE_MEDIA_ITEM = 'module.media.item';
/**
* @Serializer\Type("string")
* @MongoDB\Field(type="string")
* @var String
*/
protected $type;
/**
* @Serializer\Type("boolean")
* @MongoDB\Field(type="boolean")
* @var boolean
*/
protected $visible;
// getter/setter methods etc..
}
?>
<?php
namespace VBCMS\Bundle\AdminBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use JMS\Serializer\Annotation as Serializer;
/**
* Class TextModule
* @package VBCMS\Bundle\AdminBundle\Document
* @Serializer\AccessType("public_method")
* @MongoDB\EmbeddedDocument
*/
class TextModule extends Module {
const TEXT_TYPE_SPLASH_HEADLINE = 'splashscreen.headline';
const TEXT_TYPE_SPLASH_SUBLINE = 'splashscreen.subline';
/**
* the actual text
*
* @var string
* @Serializer\Type("string")
* @MongoDB\Field(type="string")
*/
protected $text;
/**
* how it is called in the admin interface
*
* @var string
* @Serializer\Type("string")
* @MongoDB\Field(type="string")
*/
protected $label;
/**
* @var string
* @Serializer\Type("string")
* @MongoDB\Field(type="string")
*/
protected $textType;
// getter/setter methods etc..
?>
/**
*
* @Serializer\HandlerCallback("json", direction="deserialization")
* @param JsonDeserializationVisitor $visitor
*/
public static function deserializeToObject(JsonDeserializationVisitor $visitor)
{
// modify visitor somehow to return an instance of the desired inherited module class??
}
namespace JMS\Serializer\Tests\Fixtures\Discriminator;
use JMS\Serializer\Annotation as Serializer;
/**
* @Serializer\Discriminator(field = "type", map = {
* "car": "JMS\Serializer\Tests\Fixtures\Discriminator\Car",
* "moped": "JMS\Serializer\Tests\Fixtures\Discriminator\Moped",
* })
*/
abstract class Vehicle
{
/** @Serializer\Type("integer") */
public $km;
public function __construct($km)
{
$this->km = (integer) $km;
}
}