jms/serializer Documentation

repository·master·Indexed 25 days ago

https://github.com/schmittjoh/serializer

A PHP library for serializing and deserializing complex data structures into XML and JSON formats. It supports circular references, API versioning via @Since and @Until, and property control using @Groups, @Expose, and @Exclude. The library integrates with Doctrine ORM and allows configuration through XML, YAML, or PHP Annotations. Version 3.x is the currently supported version.

Tokens
22.9K
Snippets
52
Records
98
Agent score
80%

What's inside jms/serializer

  1. Overview of jms/serializer

    master

    The jms/serializer library is a PHP tool designed to (de-)serialize data of any complexity. It is primarily used for converting complex PHP objects into formats like XML and JSON, and vice versa.

    Key capabilities include:

    • Handling circular references and complex exclusion strategies.
    • Support for built-in PHP types such as dates and intervals.
    • Integration with Doctrine ORM.
    • Support for versioning (useful for API evolution).
    • Configuration via XML, YAML, or PHP Annotations.
  2. Overview of Serializer features

    master

    The jms/serializer library is designed to (de-)serialize complex data structures. Key capabilities include:

    • Format Support: Currently supports XML and JSON.
    • Complexity Handling: Handles circular references gracefully.
    • Type Support: Includes built-in support for many PHP types, such as dates.
    • Integrations: Integrates with Doctrine ORM and other tools.
    • API Versioning: Supports versioning for API stability.
    • Configuration: Can be configured using XML, YAML, or Doctrine Annotations.
  3. Configure discriminators for polymorphic types

    master

    Discriminators allow the serializer to determine the correct class to instantiate during deserialization based on a specific field value. You can configure this at the class level or via a union_discriminator on a property.

    Class-level discriminator options:

    • field_name: The property used to determine the type.
    • map: A mapping of values to FQCNs.
    • groups: The serialization groups this discriminator applies to.
    • xml_attribute: Whether to use an XML attribute for the discriminator.
    • xml_element: Configuration for the XML element representation.
    Vendor\MyBundle\Model\ClassName:
        discriminator:
            field_name: type
            disabled: false
            map:
                some-value: ClassName
            groups: [foo, bar]
            xml_attribute: true
            xml_element:
                cdata: false
                namespace: http://www.w3.org/2005/Atom
  4. PHP 8 Attributes and Annotations Support

    master

    JMS Serializer supports PHP 8 attributes. Note the following requirements and caveats:

    • Optional Dependency: Starting from release 3.30.0, doctrine/annotations is an optional package. If you wish to continue using docblock annotations, you must explicitly require it in your composer.json.
    • Nested Attributes: Due to PHP limitations with nested attributes, some syntax (like VirtualProperty options) has changed.
    • Groups Edge Case: When using #[Groups], if you have a single item in the array where the key is value, the attribute may not work as expected. Use the named argument syntax instead: #[Groups(groups: ['value' => 'any value here'])].
    • Unions: The system automatically resolves unions of primitive types. For classes containing union attributes, you must use the #[UnionDiscriminator] attribute to specify the type.
  5. Configure virtual properties

    master

    Virtual properties are properties that do not exist as physical fields on the class but are generated during serialization. You can define them in two ways:

    1. Via Getter: Map a virtual property to an existing getter method.
    2. Via Expression: Use an expression to compute the value.

    Both types support name, serialized_name, and type configuration.

    Vendor\MyBundle\Model\ClassName:
        virtual_properties:
            getSomeProperty:
                name: optional-prop-name
                serialized_name: foo
                type: integer
            expression_prop:
                name: optional-prop-name
                exp: object.getName()
                serialized_name: foo
                type: integer
  6. Limitations of using stdClass with the serializer

    master

    When using stdClass objects, the following operations are not possible:

    • Changing the serialization order of properties.
    • Applying per-property exclusion policies.
    • Specifying extra serialization metadata for properties (e.g., serialization name, type, or XML structure).
    • Deserializing data back into stdClass objects.
  7. Fallback to default behavior using SkipHandlerException

    master
    If you are using a custom handler but want the ability to fall back to the default serialization or deserialization behavior under certain conditions, you can throw a SkipHandlerException from within your handler method. This tells the serializer to ignore your custom handler and proceed with the standard process.
  8. How VirtualProperty works

    master

    The #[VirtualProperty] attribute allows you to treat method return values as if they were object properties during serialization.

    Key behaviors:

    • Method-level: Define it on a getter method. If no name is provided, it defaults to the method name with the get prefix removed.
    • Class-level: Define it on a class to expose data using Symfony Expression Language via the exp option.
    • Limitations: This only affects serialization; it is completely ignored during deserialization.
    • PHP 8 Nested Attributes: Because PHP 8 lacks support for nested attributes, you must pass additional attributes (like SerializedName) inside the options array as an array containing the class name and an array of constructor arguments: [[ClassName::class, [args]]].
  9. Quickstart: Serialize data to JSON

    master

    For standalone projects, use the JMS\Serializer\SerializerBuilder to create a serializer instance. Once built, you can use the serialize method, specifying the format (e.g., 'json') and the data you wish to convert.

    $serializer = JMS\Serializer\SerializerBuilder::create()->build();
    $jsonContent = $serializer->serialize($data, 'json');
    echo $jsonContent; // or return it in a Response
  10. Migrate from 2.x to 3.0.0

    master

    Upgrading from 2.x to 3.x requires minimal effort.

    Key Changes:

    • The "deeper branch group exclusion strategy" introduced in 2.0.0 has been reverted to the behavior used in 1.x. If you were relying on this specific feature, you may need to adjust your configuration.
    • Deprecations introduced in 2.x remain in 3.0.0 and will likely be removed in the next major version.
  11. Implement versioning for objects using @Since and @Until

    master

    You can add versioning support to your objects to control property visibility based on a version number. This is useful for maintaining API compatibility.

    • @Since("version"): The property is only serialized if the version is greater than or equal to the specified version.
    • @Until("version"): The property is only serialized if the version is less than the specified version.

    Both annotations accept a standardized PHP version number. To use versioning, create a SerializationContext and set the version using setVersion().

  12. Map XML attributes using #[SerializedName]

    master

    When using the XML format, #[SerializedName] supports special syntax to map properties to XML attributes:

    1. Current Element Attribute: Prefix the name with @ to map the property as an attribute of the current XML element (e.g., #[SerializedName("@id")]).
    2. Sibling Element Attribute: Use the syntax "ElementName/@AttributeName" to map a property as an attribute of a sibling element. This requires a property to define the sibling element itself (typically using #[XmlElement(cdata: false)]).

    If a property mapped to an attribute is null, the attribute will not be rendered.

    <?php
    use JMS\\Serializer\Annotation as Serializer;
    
    #[Serializer\XmlRoot("user")]
    class User
    {
        #[Serializer\SerializedName("@id")]
        #[Serializer\Type("integer")]
        private $id; // Becomes an attribute "id" on the <user> element
    
        #[Serializer\SerializedName("name")]
        #[Serializer\Type("string")]
        private $name; // Becomes a child element <name> though
    
        public function __construct(int $id, string $name)
        {
            $this->id = $id;
            $this->name = $name;
        }
    }