Slide 1

Slide 1 text

Leveraging the Serializer Component Symfony Live 2012 – San Francisco – Sept. 27th

Slide 2

Slide 2 text

Hugo HAMON SensioLabs

Slide 3

Slide 3 text

Serialization is the process of converting an object state into a format that can be stored and resurrected later Wikipedia  

Slide 4

Slide 4 text

The Serializer serializes and unserializes objects.

Slide 5

Slide 5 text

Normalizers Array Serializer Object XML JSON YAML … Denormalizers Encoders Decoders

Slide 6

Slide 6 text

Objects are turned into arrays by normalizers.

Slide 7

Slide 7 text

Arrays are turned into various output formats by encoders.

Slide 8

Slide 8 text

The Serializer Interface.

Slide 9

Slide 9 text

namespace Symfony\Component\Serializer; interface SerializerInterface { /** * Serializes data in the appropriate format * * @param mixed $data any data * @param string $format format name * @return string */ public function serialize($data, $format); /** * Deserializes data into the given type. * * @param mixed $data * @param string $type * @param string $format */ public function deserialize($data, $type, $format); }

Slide 10

Slide 10 text

The Normalizer Interface.

Slide 11

Slide 11 text

namespace Symfony\Component\Serializer\Normalizer; interface NormalizerInterface { /** * Normalizes an object into a set of arrays/scalars * * @param object $object object to normalize * @param string $format format the normalization result will be encoded as * @return array|scalar */ public function normalize($object, $format = null); /** * Checks whether the given data are supported for normalization. * * @param mixed $data Data to normalize. * @param string $format The format being (de-)serialized from or into. * @return Boolean */ public function supportsNormalization($data, $format = null); }

Slide 12

Slide 12 text

The Denormalizer Interface.

Slide 13

Slide 13 text

interface DenormalizerInterface { /** * Denormalizes data back into an object of the given class. * * @param mixed $data data to restore * @param string $class the expected class to instantiate * @param string $format format the given data was extracted from * @return object */ public function denormalize($data, $class, $format = null); /** * Checks whether the given data are supported for denormalization. * * @param mixed $data Data to denormalize from. * @param string $type The class to which the data should be denormalized. * @param string $format The format being deserialized from. * @return Boolean */ public function supportsDenormalization($data, $type, $format = null); }

Slide 14

Slide 14 text

The Encoder Interface.

Slide 15

Slide 15 text

namespace Symfony\Component\Serializer\Encoder; interface EncoderInterface { /** * Encodes data into the given format * * @param mixed $data Data to encode * @param string $format Format name * * @return scalar */ public function encode($data, $format); /** * Checks whether the serializer can encode to given format * * @param string $format format name * @return Boolean */ public function supportsEncoding($format); }

Slide 16

Slide 16 text

The Decoder Interface.

Slide 17

Slide 17 text

namespace Symfony\Component\Serializer\Encoder; interface DecoderInterface { /** * Decodes a string into PHP data * * @param string $data Data to decode * @param string $format Format name * * @return mixed */ public function decode($data, $format); /** * Checks whether the serializer can decode from given format * * @param string $format format name * @return Boolean */ public function supportsDecoding($format); }

Slide 18

Slide 18 text

Basic Usage

Slide 19

Slide 19 text

use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer; use Symfony\Component\Serializer\Encoder\JsonEncoder; use Symfony\Component\Serializer\Encoder\XmlEncoder; // Register the normalizers $normalizers[] = new GetSetMethodNormalizer(); // Register the encoders $encoders[] = new JsonEncoder(); $encoders[] = new XmlEncoder(); // Create and initialize the serializer $serializer = new Serializer($normalizers, $encoders);

Slide 20

Slide 20 text

Serializing an Object.

Slide 21

Slide 21 text

$serializer ->serialize($object, 'xml') ;

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

Ignoring attributes from serialization.

Slide 24

Slide 24 text

$ignore = array('id', 'customer'); $normalizer = new GetSetMethodNormalizer(); $normalizer->setIgnoredAttributes($ignore);

Slide 25

Slide 25 text

No more ID and Customer name!

Slide 26

Slide 26 text

Unserializing a string.

Slide 27

Slide 27 text

$xml = '...'; // Convert an XML string to an array $data = $serializer->decode($xml, 'xml'); // Convert the array to an object $class = 'Acme\BookingBundle\Booking'; $booking = $serializer ->denormalize($data, $class, 'xml') ;

Slide 28

Slide 28 text

Extending the Serializer

Slide 29

Slide 29 text

Adding support for YAML serialization.

Slide 30

Slide 30 text

namespace Acme\SerializerBundle\Encoder; use Symfony\Component\Serializer\Encoder\EncoderInterface; use Symfony\Component\Yaml\Dumper; class YamlEncoder implements EncoderInterface { public function encode($data, $format) { $yaml = new Dumper(); return $yaml->dump($data, 2); } public function supportsEncoding($format) { return 'yaml' === $format; } }

Slide 31

Slide 31 text

use Acme\SerializerBundle\Encoder\YamlEncoder; $serializer = new Serializer( array(new GetSetMethodNormalizer()), array(new YamlEncoder(), ...) ); $yaml = $serializer->serialize($booking, 'yaml');

Slide 32

Slide 32 text

reference: SLT-123456 arrival: '2012-09-26' departure: '2012-09-29' designation: 'Deluxe Suite'

Slide 33

Slide 33 text

Adding support for YAML unserialization.

Slide 34

Slide 34 text

namespace Acme\SerializerBundle\Encoder; // ... use Symfony\Component\Serializer\Encoder\DecoderInterface; use Symfony\Component\Yaml\Parser; class YamlEncoder implements EncoderInterface, DecoderInterface { // ... public function decode($data, $format) { $yaml = new Parser(); return $yaml->parse($data); } public function supportsDecoding($format) { return 'yaml' === $format; } }

Slide 35

Slide 35 text

$yaml = <<decode($yaml, 'yaml'); $booking = $serializer->denormalize($data, $class, 'yaml'); echo $booking->getReference();

Slide 36

Slide 36 text

The JMS Serializer Bundle

Slide 37

Slide 37 text

The Serializer service.

Slide 38

Slide 38 text

$s = $container->get('serializer'); $json = $s->serialize($object, 'json'); $xml = $s->serialize($object, 'xml'); $yml = $s->serialize($object, 'yml'); $type = 'Acme\BookingBundle\Booking'; $obj = $s->deserialize($xml, $type, 'xml'); $obj = $s->deserialize($yml, $type, 'yml');

Slide 39

Slide 39 text

Twig helpers.

Slide 40

Slide 40 text

{# uses JSON #} {{ booking | serialize }} {# Custom output format #} {{ booking | serialize('json') }} {{ booking | serialize('xml') }} {{ booking | serialize('yml') }}

Slide 41

Slide 41 text

Customizing the XML root node.

Slide 42

Slide 42 text

namespace Acme\BookingBundle; use JMS\SerializerBundle\Annotation\XmlRoot; /** * @XmlRoot("booking") */ class Booking { // ... }

Slide 43

Slide 43 text

SLT-123456 2012-09-26 2012-09-29 Deluxe Suite

Slide 44

Slide 44 text

Serializing a property to a XML attribute.

Slide 45

Slide 45 text

namespace Acme\BookingBundle; use JMS\SerializerBundle\Annotation\XmlRoot; use JMS\SerializerBundle\Annotation\XmlAttribute; /** @XmlRoot("booking") */ class Booking { /** @XmlAttribute */ private $reference; // ... }

Slide 46

Slide 46 text

2012-09-26 2012-09-29 Deluxe Suite

Slide 47

Slide 47 text

Serializing an object to a single XML node

Slide 48

Slide 48 text

namespace Acme\BookingBundle; use JMS\SerializerBundle\Annotation\XmlRoot; /** * @XmlRoot("booking") */ class Booking { /** @var Price */ private $price; }

Slide 49

Slide 49 text

namespace Acme\BookingBundle; use JMS\SerializerBundle\Annotation\XmlAttribute; use JMS\SerializerBundle\Annotation\XmlValue; class Price { /** @XmlValue */ private $amount; /** @XmlAttribute */ private $vat; /** @XmlAttribute */ private $currency; }

Slide 50

Slide 50 text

$booking = new Booking(); $booking->setReference('SLT-123456'); // ... $booking->setPrice(new Price(120, 12, 'EUR')); 2012-09-29 120

Slide 51

Slide 51 text

Excluding or Exposing properties.

Slide 52

Slide 52 text

namespace Acme\BookingBundle; use JMS\SerializerBundle\Annotation\ExclusionPolicy; use JMS\SerializerBundle\Annotation\Expose; use JMS\SerializerBundle\Annotation\XmlRoot; /** * @ExclusionPolicy("all") * @XmlRoot("booking") */ class Booking { /** @Expose */ private $reference; }

Slide 53

Slide 53 text

SLT-123456

Slide 54

Slide 54 text

namespace Acme\BookingBundle; use JMS\SerializerBundle\Annotation\ExclusionPolicy; use JMS\SerializerBundle\Annotation\Exclude; use JMS\SerializerBundle\Annotation\XmlRoot; /** * @ExclusionPolicy("none") * @XmlRoot("booking") */ class Booking { /** @Exclude */ private $price; }

Slide 55

Slide 55 text

SLT-123456 2012-09-26 2012-09-29 Deluxe Suite

Slide 56

Slide 56 text

Managing objects properties versioning

Slide 57

Slide 57 text

namespace Acme\BookingBundle; // ... use JMS\SerializerBundle\Annotation\Since; use JMS\SerializerBundle\Annotation\SerializedName; // ... class Booking { /** * @Since("1.8.4") * @SerializedName("loyalty") */ private $loyaltyNumber; // ... }

Slide 58

Slide 58 text

namespace Acme\BookingBundle; // ... use JMS\SerializerBundle\Annotation\Until; // ... class Booking { /** * @Until("1.8.3") * @SerializedName("loyalty") */ private $membershipNumber; // ... }

Slide 59

Slide 59 text

$booking->setMembershipNumber('3942945839'); $booking->setLoyaltyNumber('0973525332'); $serializer->setVersion('1.8.2'); 3942945839

Slide 60

Slide 60 text

$booking->setMembershipNumber('3942945839'); $booking->setLoyaltyNumber('0973525332'); $serializer->setVersion('1.9'); 0973525332

Slide 61

Slide 61 text

Offering several views of a serialized object.

Slide 62

Slide 62 text

namespace Acme\BookingBundle; use JMS\SerializerBundle\Annotation\Groups; class Booking { /** @Groups({ "list" }) */ private $id; /** @Groups({ "list", "details" }) */ private $reference; /** @Groups({ "details" }) */ private $designation; }

Slide 63

Slide 63 text

SLT-123456 Deluxe Suite $serializer = $this->get('serializer'); $serializer->setGroups(array('details')); $serializer->serialize($booking, 'xml');

Slide 64

Slide 64 text

Forcing the serializer to call getters & setters.

Slide 65

Slide 65 text

use JMS\SerializerBundle\Annotation\AccessType; class Booking { /** @AccessType("public_method") */ private $arrival; public function setArrival($arrival) { $this->arrival = new \DateTime($arrival); } public function getArrival() { return $this->arrival->format('m/d/Y'); } }

Slide 66

Slide 66 text

SLT-123456 09/26/2012 2012-09-29

Slide 67

Slide 67 text

Mapping a property to another getter or setter method.

Slide 68

Slide 68 text

use JMS\SerializerBundle\Annotation\Accessor; class Booking { /** * @Accessor( * setter = "setShortDesignation", * getter = "getShortDesignation" * ) */ private $designation; }

Slide 69

Slide 69 text

Customizing the order in which properties are serialized.

Slide 70

Slide 70 text

use JMS\SerializerBundle\Annotation\AccessOrder; /** * @AccessOrder("alphabetical") */ class Booking { // ... }

Slide 71

Slide 71 text

use JMS\SerializerBundle\Annotation\AccessOrder; /** * @AccessOrder(custom = { * "reference", * "arrival", * "departure" * }) */ class Booking { // ... }

Slide 72

Slide 72 text

SLT-123456 2012-09-26 2012-09-29 Deluxe Suite 3942945839 119.6

Slide 73

Slide 73 text

Typing properties for a complete unserialization.

Slide 74

Slide 74 text

namespace Acme\BookingBundle; use JMS\SerializerBundle\Annotation\Type; class Booking { /** @Type("string") */ private $reference; /** @Type("DateTime") */ private $arrival; /** @Type("Acme\BookingBundle\Price") */ private $price; }

Slide 75

Slide 75 text

No content