spiral-packages/symfony-serializer

Spiral 框架的 Symfony 序列化器桥接器

2.2.0 2024-03-26 07:52 UTC

This package is auto-updated.

Last update: 2024-09-16 09:56:21 UTC


README

PHP Version Require Latest Stable Version phpunit psalm Total Downloads

此包为 Spiral 框架默认序列化器列表提供扩展,允许您轻松地将对象序列化为各种格式,如 JSONXMLCSVYAML

注意 在官方 文档 中了解更多关于 spiral/serializer 组件的信息。

如果您正在构建 REST API 或使用队列,则此包特别有用,因为它允许您使用对象而不是简单的数组作为有效载荷。

本文档将指导您完成安装过程,并提供如何使用此包进行对象序列化和反序列化的示例。

要求

请确保您的服务器已配置以下 PHP 版本和扩展

  • PHP 8.1+
  • Spiral 框架 ^3.7
  • Symfony 序列化器组件 ^6.4 || ^7.0
  • Symfony 属性访问组件 ^6.4 || ^7.0

安装

您可以通过 composer 安装此包

composer require spiral-packages/symfony-serializer

在包安装后,您需要从包中注册引导加载器。

protected const LOAD = [
    // ...
    \Spiral\Serializer\Symfony\Bootloader\SerializerBootloader::class,
];

注意 引导加载器 Spiral\Serializer\Bootloader\SerializerBootloader 可以被移除。如果您使用 spiral-packages/discoverer,则无需自行注册引导加载器。

配置

此包包含默认的 normalizersencodersmetadataLoader 配置。但是,您可以根据项目需求更改这些配置。

有两种方式来配置此包

配置文件

您可以在 app/config/symfony-serializer.php 中创建一个配置文件,并定义用于扩展默认配置的 normalizersencodersSymfony\Component\Serializer\Mapping\Loader\LoaderInterface,这些参数用于 Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory

以下是一个配置文件的示例

use Symfony\Component\Serializer\Encoder;
use Symfony\Component\Serializer\Normalizer;
use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader;
use Spiral\Core\Container\Autowire;

return [
    'normalizers' => [
        new Normalizer\UnwrappingDenormalizer(),
        new Normalizer\ProblemNormalizer(debug: false),
        new Normalizer\UidNormalizer(),
        new Normalizer\JsonSerializableNormalizer(),
        new Normalizer\DateTimeNormalizer(),
        new Normalizer\ConstraintViolationListNormalizer(),
        new Normalizer\MimeMessageNormalizer(new Normalizer\PropertyNormalizer()),
        new Normalizer\DateTimeZoneNormalizer(),
        new Normalizer\DateIntervalNormalizer(),
        new Normalizer\FormErrorNormalizer(),
        new Normalizer\BackedEnumNormalizer(),
        new Normalizer\DataUriNormalizer(),
        new Autowire(Normalizer\ArrayDenormalizer::class), // by Autowire
        Normalizer\ObjectNormalizer::class, // by class string
    ],
    'encoders' => [
        new Encoder\JsonEncoder(),
        new Encoder\CsvEncoder(),
        Encoder\XmlEncoder::class,
        new Autowire(Encoder\YamlEncoder::class),
    ],
    'metadataLoader' => new AttributeLoader() // by default
 //  Other available loaders:
 // 'metadataLoader' => new YamlFileLoader('/path/to/your/definition.yaml')
 // 'metadataLoader' => new XmlFileLoader('/path/to/your/definition.xml')
];

引导加载器

此包提供的 Spiral\Serializer\Symfony\EncodersRegistryInterfaceSpiral\Serializer\Symfony\NormalizersRegistryInterface 用于添加您自己的 normalizers 或 encoders。您可以使用这些接口提供的 register 方法来注册您自己的 normalizersencoders

以下是一个示例

namespace App\Application\Bootloader;

use Spiral\Serializer\Symfony\EncodersRegistryInterface;
use Spiral\Serializer\Symfony\NormalizersRegistryInterface;
use Spiral\Boot\Bootloader\Bootloader;

final class AppBootloader extends Bootloader
{
    public function boot(
        NormalizersRegistryInterface $normalizersRegistry,
        EncodersRegistryInterface $encodersRegistry,
    ): void {
        // Add CustomNormalizer before ObjectNormalizer
        $normalizersRegistry->register(normalizer: new CustomNormalizer(), priority: 699);

        $encodersRegistry->register(new CustomEncoder());
    }
}

用法

此包提供了一系列序列化器,可用于序列化和反序列化对象。

此包中可用的序列化器有:symfony-jsonsymfony-csvsymfony-xmlsymfony-yaml

警告 yaml 编码器需要 symfony/yaml 包,并且当该包未安装时被禁用。安装 symfony/yaml 包后,编码器将自动启用。

以下是如何使用这些序列化器的几种方法

1. 设置默认序列化器

您可以通过设置 DEFAULT_SERIALIZER_FORMAT 环境变量来将所需的 Symfony 序列化器设置为默认应用序列化器。

DEFAULT_SERIALIZER_FORMAT=symfony-json

一旦设置了默认序列化器,您就可以从容器中请求 Spiral\Serializer\SerializerInterface 并使用它来序列化和反序列化对象。

序列化

use Spiral\Serializer\SerializerInterface;
use App\Repository\PostRepository;

final class PostController
{
    public function __construct(
        private readonly SerializerInterface $serializer,
        private readonly PostRepository $repository,
    ) {}

    public function show(string $postId): string
    {
        $post = $this->repository->find($postId);

        return $this->serializer->serialize($post);
    }
}

反序列化

use App\Entity\Post;use Spiral\Serializer\SerializerInterface;

final class PostService
{
    public function __construct(
        private readonly SerializerInterface $serializer,
        private readonly HttpClient $http,
    ) {}

    public function show(string $postId): Post
    {
        $json = $this->http->get('https://example.com/posts/' . $postId);

        return $this->serializer->unserialize($json, Post::class);
    }
}

2. 使用序列化管理器

您可以通过名称从 Spiral\Serializer\SerializerManager 请求所需的序列化器。一旦您有了序列化器,您就可以使用它来序列化和反序列化对象。

序列化

use Spiral\Serializer\SerializerManager;
use Spiral\Serializer\SerializerInterface;
use App\Repository\PostRepository;

final class PostController
{
    private readonly SerializerInterface $serializer;

    public function __construct(
        SerializerManager $manager,
        private readonly PostRepository $repository,
    ) {
        $this->serializer = $manager->getSerializer('symfony-json');
    }

    public function show(string $postId): string
    {
        $post = $this->repository->find($postId);

        return $this->serializer->serialize($post);
    }
}

反序列化

use App\Entity\Post;use Spiral\Serializer\SerializerInterface;

final class PostService
{
    private readonly SerializerInterface $serializer;

    public function __construct(
        SerializerManager $manager,
        private readonly HttpClient $http,
    ) {
        $this->serializer = $manager->getSerializer('symfony-json');
    }

    public function show(string $postId): Post
    {
        $json = $this->http->get('https://example.com/posts/' . $postId);

        return $this->serializer->unserialize($json, Post::class);
    }
}

或者,您可以使用管理类中的 serializeunserialize 方法

use Psr\Container\ContainerInterface;
use Spiral\Serializer\SerializerManager;
use App\Repository\PostRepository;
use App\Entity\Post;

/** @var PostRepository $repository */
$post = $repository->find($postId);
/** @var ContainerInterface $container */
$serializer = $container->get(SerializerManager::class);

$serializedString = $manager->serialize($post , 'symfony-json');

$post = $manager->unserialize($serializedString , Post::class, 'symfony-json');

3. 与 Symfony Serializer 一起使用

您还可以直接通过容器请求 Symfony\Component\Serializer\SerializerInterface 来使用 Symfony Serializer。一旦您有了序列化器,您就可以使用它来 serializedeserialize 对象。

以下是一个示例

use Symfony\Component\Serializer\SerializerInterface;

$serializer = $this->container->get(SerializerInterface::class);

$result = $serializer->serialize($payload, 'symfony-json', $context);
$result = $serializer->deserialize($payload, Post::class, 'symfony-json', $context);

其他方法

Symfony Serializer 管理器提供了一些额外的方法来处理数据

  • normalize:此方法接受 dataformat 并返回表示规范化数据的值。您还可以传递上下文参数来控制规范化过程。

  • denormalize:此方法接受 datatypeformatcontext,并返回表示反规范化数据的对象。

  • supportsNormalization:此方法接受 dataformatcontext,并返回一个指示给定数据是否可以通过序列化器进行规范化的布尔值。

  • supportsDenormalization:此方法接受 datatypeformatcontext,并返回一个指示给定数据是否可以通过序列化器进行反规范化的布尔值。

  • encode:此方法接受 dataformatcontext,并返回表示编码数据的字符串。

  • decode:此方法接受 dataformatcontext,并返回表示解码数据的值。

  • supportsEncoding:此方法接受一个 format 和一个 context,并返回一个指示给定格式是否可以由序列化器用于编码数据的布尔值。

  • supportsDecoding:此方法接受一个 format 和一个 context,并返回一个指示给定格式是否可以由序列化器用于解码数据的布尔值。

use Spiral\Serializer\SerializerManager;

$manager = $this->container->get(SerializerManager::class);

// Getting a serializer `Spiral\Serializer\Symfony\Serializer`
$serializer = $manager->getSerializer('symfony-json');

$serializer->normalize($data, $format, $context);
$serializer->denormalize($data, $type, $format, $context);

$serializer->supportsNormalization($data, $format, $context);
$serializer->supportsDenormalization($data, $type, $format, $context);

$serializer->encode($data, $format, $context);
$serializer->decode($data, $format, $context);

$serializer->supportsEncoding($format, $context);
$serializer->supportsDecoding($format, $context);

这些方法提供了处理不同数据格式的额外灵活性,并在某些场景中非常有用。

测试

composer test

变更日志

有关最近更改的更多信息,请参阅 CHANGELOG

许可证

MIT 许可证(MIT)。有关更多信息,请参阅 许可证文件