New in Symfony 2.7: Serialization Groups
Warning: This post is about an unsupported Symfony version. Some of this information may be out of date. Read the most recent Symfony Docs.
Contributed by
Kévin Dunglas
in #12092.
The Symfony Serializer component is used to turn PHP objects into a specific format (XML, JSON, YAML, ...) and the other way around. In order to maintain its simplicity, we've limited the scope of the component and that's why it's one of the Symfony components with less new features since its introduction.
In Symfony 2.7 we've decided to reverse this trend and we're introducing a new feature to serialize/deserialize different sets of object attributes. Consider the following object that includes properties aimed to administrators, affiliates and regular users:
1 2 3 4 5 6 7 8 9 10 11
class Product
{
// this property is exclusive for administrators
public $itemsSold;
// this property is visible by administrators and affiliates
public $commission;
// this property is visible by all (administrators, affiliates, users)
public $price;
}
The definition of serialization can be specified using annotations, XML or YAML. In case of using annotations, define serialization groups as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
use Symfony\Component\Serializer\Annotation\Groups;
class Product
{
/**
* @Groups({"admins"})
*/
public $itemsSold;
/**
* @Groups({"admins", "affiliates"})
*/
public $commission;
/**
* @Groups({"admins", "affiliates", "users"})
*/
public $price;
}
Now that serialization groups have been defined, you can serialize only the attributes that belong to the given groups:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Doctrine\Common\Annotations\AnnotationReader;
$product = new Product();
$product->itemsSold = 20;
$product->commission = 7.5;
$product->price = 19.99;
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$normalizer = new PropertyNormalizer($classMetadataFactory);
$serializer = new Serializer([$normalizer]);
$data = $serializer->normalize($product, null, ['groups' => ['admins']]);
// $data = ['itemsSold' => 20, 'commission' => 7.5, 'price' => 19.99];
$data = $serializer->normalize($product, null, ['groups' => ['affiliates']]);
// $data = ['comission' => 7.5, 'price' => 19.99];
$data = $serializer->normalize($product, null, ['groups' => ['users']]);
// $data = ['price' => 19.99];
$data = $serializer->normalize($product, null, ['groups' => ['affiliates', 'users']]);
// $data = ['commission' => 7.5, 'price' => 19.99];
Similarly, you can define the groups to user when deserializing contents:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Doctrine\Common\Annotations\AnnotationReader;
$product = new Product();
$product->itemsSold = 20;
$product->commission = 7.5;
$product->price = 19.99;
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$normalizer = new PropertyNormalizer($classMetadataFactory);
$serializer = new Serializer(array($normalizer));
$product = $serializer->denormalize(
['itemsSold' => 20, 'price' => 19.99, 'commission' => 7.5],
'Product',
null,
['groups' => ['affiliates', 'users']]
);
// $product = Product(price: 19.99, commission: 7.5)
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
- missing $ for the price property (in both class definitions)
- the instantiation of $classMetadataFactory is missing in all code snippets, while it is one of the changes in 2.7
// $data = ['commission' => 7.5, 'price' => 19.99];
(This in the exemple of serializing. The exemple of deserialization is correct)
use Symfony\Component\Serializer\Annotation\Groups;