This package provides an extension to the default list of serializers in Spiral Framework, allowing you to easily
serialize and deserialize objects into various formats such as JSON
, XML
, CSV
, and YAML
.
Note Read more about spiral/serializer component in the official documentation.
If you are building a REST API or working with queues, this package will be especially useful as it allows you to use objects as payload instead of simple arrays.
This documentation will guide you through the installation process and provide examples of how to use the package to serialize and deserialize your objects.
Make sure that your server is configured with following PHP version and extensions:
- PHP 8.1+
- Spiral framework ^3.7
- Symfony Serializer Component ^6.4 || ^7.0
- Symfony PropertyAccess Component ^6.4 || ^7.0
You can install the package via composer:
composer require spiral-packages/symfony-serializer
After package install you need to register bootloader from the package.
protected const LOAD = [
// ...
\Spiral\Serializer\Symfony\Bootloader\SerializerBootloader::class,
];
Note Bootloader
Spiral\Serializer\Bootloader\SerializerBootloader
can be removed. If you are usingspiral-packages/discoverer
, you don't need to register bootloader by yourself.
The package comes with default configurations for normalizers
, encoders
, and metadataLoader
. However, you can
change these configurations based on your project's requirements.
There are two ways to configure the package:
You can create a configuration file app/config/symfony-serializer.php
and define normalizers
, encoders
,
and Symfony\Component\Serializer\Mapping\Loader\LoaderInterface
for Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory
used by the Symfony Serializer component
parameters to extend the default configuration.
Here is an example of the configuration file:
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\EncodersRegistryInterface
and Spiral\Serializer\Symfony\NormalizersRegistryInterface
provided by the package to add your own normalizers or encoders. You can register your own normalizers
or encoders
using the register
method provided by these interfaces.
Here is an example:
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());
}
}
The package provides a list of serializers that can be used to serialize and deserialize objects.
The serializers available in this package are: symfony-json
, symfony-csv
, symfony-xml
, symfony-yaml
.
Warning The
yaml
encoder requires thesymfony/yaml
package and is disabled when the package is not installed. Install thesymfony/yaml
package and the encoder will be automatically enabled.
Here are several ways to use these serializers:
You can set a desired Symfony serializer as the default application serializer by setting
the DEFAULT_SERIALIZER_FORMAT
environment variable.
DEFAULT_SERIALIZER_FORMAT=symfony-json
Once the default serializer is set, you can request the Spiral\Serializer\SerializerInterface
from the container and
use it to serialize and deserialize objects.
Serialization:
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);
}
}
Deserialization:
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);
}
}
You can request a desired serializer from Spiral\Serializer\SerializerManager
by its name. Once you have the
serializer, you can use it to serialize and deserialize objects.
Serialization:
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);
}
}
Deserialization:
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);
}
}
Alternatively, you can use the serialize
and unserialize
methods of the manager class:
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 */
$manager = $container->get(SerializerManager::class);
$serializedString = $manager->serialize($post , 'symfony-json');
$post = $manager->unserialize($serializedString , Post::class, 'symfony-json');
You can also use the Symfony Serializer directly by requesting the Symfony\Component\Serializer\SerializerInterface
from the container. Once you have the serializer, you can use it to serialize
and deserialize
objects.
Here's an example:
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 Manager provides additional methods to work with data:
-
normalize: This method takes in
data
and aformat
and returns a value that represents the normalized data. The context parameter can also be passed to control the normalization process. -
denormalize: This method takes in
data
, atype
, aformat
, and acontext
, and returns an object that represents the denormalized data. -
supportsNormalization: This method takes in
data
, aformat
, and acontext
, and returns aboolean
indicating whether the given data can be normalized by the serializer. -
supportsDenormalization: This method takes in
data
, atype
, aformat
, and acontext
, and returns aboolean
indicating whether the given data can be denormalized by the serializer. -
encode: This method takes in
data
, aformat
, and acontext
, and returns astring
that represents the encoded data. -
decode: This method takes in
data
, aformat
, and acontext
, and returns avalue
that represents the decoded data. -
supportsEncoding: This method takes in a
format
and acontext
, and returns aboolean
indicating whether the given format can be used to encode data by the serializer. -
supportsDecoding: This method takes in a
format
and acontext
, and returns aboolean
indicating whether the given format can be used to decode data by the serializer.
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);
These methods provide additional flexibility for working with different data formats and can be useful in certain scenarios.
composer test
Please see CHANGELOG for more information on what has changed recently.
The MIT License (MIT). Please see License File for more information.