Nuevo en Symfony 4.1: Serializar y deserializar clases abstractas
Cuando se trabaja con objetos que son muy parecidos o comparten muchas propiedades es común usar interfaces o clases abstractas. El problema de las clases que heredan de otras clases abstractas es que el componente Serializer no sabe cómo serializarlas o deserializarlas correctamente.
En Symfony 4.1 hemos mejorado el serializador para soportar esta funcionalidad
mediante un "discriminador de clases" ("discriminator class mapping" en
inglés). Imagina una aplicación que define una clase CodeRepository
abstracta
de la que heredan las clases GitHubCodeRepository
y BitBucketCodeRepository
.
El siguiente ejemplo muestra cómo serializar/deserializar objetos de ese tipo
cuando se utiliza el componente Serializer de forma independiente:
// ... $discriminator = new ClassDiscriminatorResolver(); // $type es la propiedad que se utiliza para discriminar entre clases $discriminator->addClassMapping( CodeRepository::class, new ClassDiscriminatorMapping('type', [ 'github' => GitHubCodeRepository::class, 'bitbucket' => BitBucketCodeRepository::class, ]) ); // pasa el discriminador como último argumento del normalizador $serializer = new Serializer( array(new ObjectNormalizer(null, null, null, null, $discriminator)), array('json' => new JsonEncoder()) ); // al serializar, el discriminador sabe que el valor de la propiedad "type" // de los objetos de tipo GitHubCodeRepository debe ser: {"type": "github"} $serialized = $serializer->serialize(new GitHubCodeRepository()); // al deserializar utilizando la clase abstracta CodeRepository, el discriminador // utiliza el valor de "type" para saber que $repository es de tipo GitHubCodeRepository $repository = $serializer->unserialize($serialized, CodeRepository::class, 'json');
Como siempre, utilizar esta funcionalidad dentro de una aplicación Symfony es mucho más sencillo. Simplemente configura el discriminador en un archivo YAML, XML o incluso en una anotación PHP:
namespace App\Repository; use Symfony\Component\Serializer\Annotation\DiscriminatorMap; /** * @DiscriminatorMap(typeProperty="type", mapping={ * "github"="App\Repository\GitHubCodeRepository", * "bitbucket"="App\Repository\BitBucketCodeRepository" * }) */ interface CodeRepository { // ... }
Puedes leer más sobre esta funcionalidad en la sección Serializing Interfaces and Abstract Classes de la documentación oficial del componente Serializer.
Esta funcionalidad fue contribuida por Samuel Roze en el pull request #24375.
Fuente: New in Symfony 4.1: Serialize and deserialize from abstract classes
Comentarios
Proyectos Symfony destacados
La plataforma de eCommerce 100% Symfony que rivaliza con Magento y PrestaShop. Ver más
Síguenos en @symfony_es para acceder a las últimas noticias.