webit/doctrine-jms-json

使用 JMS Serializer 转换复杂对象

3.1.1 2023-03-30 07:46 UTC

This package is auto-updated.

Last update: 2024-08-30 01:49:33 UTC


README

使用 Doctrine 通过 JMS Serializer 持久化值对象。DBAL 类型支持 JMS Serializer 可以处理的所有内容(标量、数组、Doctrine 集合、DateTime 等)。

安装

"webit/doctrine-jms-json": "^2.0.0" 添加到你的 composer.json 的 require 部分

{
    "require": {
        "webit/doctrine-jms-json": "^3.0.0"
    }
}

用法

配置注册新的 Doctrine DBAL 类型并配置序列化器

# boostrap.php

use Doctrine\DBAL\Types\Type;
use Webit\DoctrineJmsJson\DBAL\JmsJsonType;
use JMS\Serializer\SerializerBuilder;
use Webit\DoctrineJmsJson\Serializer\Type\DefaultSerializerTypeResolver;

Type::addType('jms_json', 'Webit\DoctrineJmsJson\DBAL\JmsJsonType');

$serializer = SerializerBuilder::create()->build();
// initialize JmsJsonType
JmsJsonType::initialize($serializer, new DefaultSerializerTypeResolver());

现在你可以在 Doctrine 字段映射中使用 "jms_json" 作为类型。

请参阅 JMS Serializer 的完整配置 这里 请参阅 Doctrine 映射的完整文档 这里 请参阅 Doctrine 自定义类型文档 这里

示例

"jms_json" DBAL 类型可以非常方便地存储 值对象 或结构可能变化的对象。

以网页上的一个 滑块 为例。让类 BannerSet 包含 Slider 配置。

interface Slider
{
}

class BannerSet
{
    private $id;
    
    /** Slider */
    private $slider;
    
    /**
     * @return Slider
     */
    public function slider()
    {
        return $this->slider;
    }
    
    /**
     * @param Slider $slider
     */
    public function changeSlider(Slider $slider)
    {
        $this->slider = $slider;
    }
}

JavaScript 滑块配置有很多种,我们事先不知道其结构。让我们引入两种实现

use JMS\Serializer\Annotation as JMS;

class Slider1 implements Slider
{
    /**
     * @JMS\Type("string")
     */
    private $theme;
    
    /**
     * @JMS\Type("double")
     */
    private $slideTime;
    
    // ...
}

class Slider2 implements Slider
{ 
    /**
     * @JMS\Type("array<string>")
     */
    private $effects;

    /**
     * @JMS\Type("boolean")
     */
    private $stopOnHover;
    
    /**
     * @JMS\Type("integer")
     */
    private $pauseTime;
 
    // ...
}

要使用 Doctrine ORM 将 BannerSet 持久化到数据库,我们需要提供映射。使用标准的关系方法,我们需要映射 BannerSet 和每个 Slider(可能使用 [单表继承])。这意味着,我们将有两个数据库表 "banner_set" 和 "slider",它们之间存在一对一的关系 - 对于存储滑块配置来说相当复杂。而且,这种方法需要将 Slider 实例作为实体存储(我们必须引入 ID 以存储在表中),这破坏了我们的模型。

滑块配置只是我们需要存储的对象,我们不需要查询它。因此,将其存储在 "banner_set" 表的一个列中的 JSON 格式中会更简单。

BannerSet Doctrine 映射文件将看起来像这样

entity:
    class: BannerSet
    id:
        id:
            type: int
    fields:
        slider:
            type: jms_json

就是这样!

显然,我们需要为 Slider1Slider2 提供序列化器的映射(可以通过不同的方式完成,例如通过注释 - 查看更多详细信息,请参阅 JMSSerializer 文档)。

Symfony 2/3 集成

请参阅 WebitDoctrineJsonBundle Symfony 2/3 集成。

测试

composer install
./vendor/bin/phpunit

变更日志

版本 2.0.0

引入了对原生 JSON 类型数据库字段的支持。内部数据以有效的 JSON 格式存储('{"_jms_type": "Deserialisation Type", "data": "DATA TO BE DESERIALISED"}')。这破坏了与版本 1.x 的向后兼容性。版本 1.x 不能升级到 2.x 而不进行手动转换已保存的数据。

版本 2.1.0

在转换为PHP值(从数据库读取)时,与版本 1.x 兼容。请注意,从版本 1.x 格式读取的数据将在实体的刷新过程中自动转换为新的格式。

版本 3.0.0

支持更高的JMS Serializer版本(2.x、3.x)。此版本需要PHP >= 7.2。