如何在Symfony Serializer中反序列化对象数组?

Mik*_*ers 10 php serializer symfony

是否可以Symfony Serializer反序列化属性中的对象数组?我有一个Boss$Npc = []需要持有一个Npc对象数组的属性.我确实在文档中看到了一些示例,但他们没有说明此功能.我有一个带有NPC数组的json字符串例如:

class Boss {

    private $Npc = [];    

    /**
    * @return Npc[]
    */
    public function getNpcs(): array
    {
        return $this->npcs;
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用的是php7.1和symfony/serializer版本^ 3.3.

编辑:我已经尝试过PhpDocExtractor,但它不会让我安装它.:(

编辑:这是一个可能的JSON值:

{
    "bossname": "Epic boss!",
    "npcs": [{
        "id": 24723,
        "name": "Selin Fireheart",
        "urlSlug": "selin-fireheart",
        "creatureDisplayId": 22642
    }]
}
Run Code Online (Sandbox Code Playgroud)

Mik*_*ers 8

我找到了一种方法:)。我通过Composer安装了Symfony PropertyAccess软件包。使用此软件包,您可以添加加法器,去除器和麻烦。这样,Symfony序列化程序将自动用正确的对象填充数组。例:

private $npcs = [];

public function addNpc(Npc $npc): void
{
    $this->npcs[] = $npc;
}

public function hasNpcs(): bool
{
    return count($this->npcs) > 0
}
Run Code Online (Sandbox Code Playgroud)

等等

这样,您可以将ObjectNormalizer用于:

$normalizer = new ObjectNormalizer(null, null, null, new ReflectionExtractor());
Run Code Online (Sandbox Code Playgroud)

编辑:至少从v3.4开始,您还必须创建卸妆方法。否则,它将不起作用(无错误或警告)。

  • 至少对于v3.4,您已经**设置了一个卸妆工具才能正常工作(我花了几个小时来调试它)。确保检查您的尿液。 (2认同)

Dan*_*iel 7

以下(完整)示例适用于我的 Symfony 5.3 组件。它结合了上面的一些内容并添加了一些更必要的部分:

序列化器需要包含ArrayDenormalizer以及ObjectNormalizer. 需要ObjectNormalizer正确的配置。完整的创建可能如下所示:

return new Serializer(
    [
        new ArrayDenormalizer(),
        new DateTimeNormalizer(),
        new ObjectNormalizer(
            null,
            null,
            null,
            new ReflectionExtractor()
        ),
    ],
    [
        new JsonEncoder(),
    ]
);
Run Code Online (Sandbox Code Playgroud)

对于规范化器/反规范化器来说,顺序似乎很重要,可能是由于优先级。放在DateTimeNormalizer后面就ObjectNormalizer不行了。

目标类需要提供三个方法才能允许映射其他类的数组:

class Place
{
    /**
     * @var OpeningHour[]
     */
    protected $openingHours = [];

    /**
     * @return OpeningHour[]
     */
    public function getOpeningHoursSpecification(): array
    {
        return $this->openingHours;
    }

    public function addOpeningHoursSpecification(OpeningHour $openingHour): void
    {
        $this->openingHours[] = $openingHour;
    }

    public function removeOpeningHoursSpecification(OpeningHour $openingHour): void
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

所有这三种方法都需要存在。第一个是为了允许序列化器获取现有值并允许比较。另外两个需要存在,以便通过添加缺失的实体和删除不再存在的实体来调整现有值以匹配预期值。

上面没有提供删除的实现,因为这是从单向项目中获取的。


Jim*_*nse 6

我已经挣扎了这么多小时没有得到结果。每次我添加一个加法器函数时,objectnormalizer 都想调用这个函数,但得到一个错误,比如“字段 xyz 应该是 xyz[] 类型,给定数组”。

这是因为我忘记将ArrayDenormalizer加到序列化器的规范化器池中。添加后,一切正常。

希望这对某人有帮助。


db3*_*306 -3

是的,您可以反序列化数组,但您需要在第二个参数上提供对象以及它实际上是数组的信息。你可以这样做:

use Symfony\Component\Serializer\Serializer;

class Boss {

    private $Npc = [];    

    /**
    * @return Npc[]
    */
    public function getNpcs(): array
    {
        return $serializer->deserialize($this->npcs, 'Acme\Npc[]', 'json');

    }
}
Run Code Online (Sandbox Code Playgroud)

您可以在处理数组的文档中找到更多相关信息