Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Serializer Laravel Package

symfony/serializer

Symfony Serializer component for converting objects and complex data structures to/from arrays, JSON, XML and more. Supports object graphs, custom normalizers/encoders, and flexible context options for reliable serialization and deserialization.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup in Laravel

Install via Composer:

composer require symfony/serializer

First Use Case: Serializing an Eloquent Model to JSON

use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;

// In a service or controller
$encoders = [new JsonEncoder()];
$normalizers = [new ObjectNormalizer()];
$serializer = new Serializer($normalizers, $encoders);

$user = User::find(1);
$json = $serializer->serialize($user, 'json');

First Use Case: Deserializing JSON to a Model

$data = json_decode('{"name":"John","email":"john@example.com"}', true);
$user = $serializer->deserialize($data, User::class, 'array');

Where to Look First

  1. Official Documentation – Covers core concepts, normalizers, and encoders.
  2. ObjectNormalizer – Handles basic object-to-array conversion (most commonly used).
  3. Serializer class – The main entry point for serialization/deserialization.
  4. Encoder interfaces – For format-specific handling (e.g., JsonEncoder, XmlEncoder).

Implementation Patterns

Common Workflows

1. Basic Serialization/Deserialization

// Serialize to JSON
$json = $serializer->serialize($object, 'json');

// Deserialize from JSON
$object = $serializer->deserialize($json, stdClass::class, 'json');

2. Handling Nested Objects

Leverage ObjectNormalizer with ignoredAttributes or circularReferenceHandler:

$normalizer = new ObjectNormalizer(null, null, null, [
    'ignoredAttributes' => ['password', 'apiToken'],
    'circularReferenceHandler' => function ($object) {
        return 'REF_' . spl_object_hash($object);
    }
]);

3. Custom Normalizers

Extend ObjectNormalizer or create a custom normalizer for domain-specific logic:

use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

class UserNormalizer implements NormalizerInterface
{
    public function normalize($object, string $format = null, array $context = [])
    {
        return [
            'id' => $object->id,
            'name' => $object->name,
            'email' => $object->email,
            'role' => $object->role->value, // Handle relationships
        ];
    }

    public function supportsNormalization($data, string $format = null): bool
    {
        return $data instanceof User;
    }
}

4. Grouped Serialization (API Resources)

Use @Groups annotations or context-based filtering:

// In User entity
use Symfony\Component\Serializer\Annotation\Groups;

class User
{
    #[Groups(['api:read'])]
    public string $name;

    #[Groups(['api:write'])]
    public string $email;
}

// Serialize with groups
$serializer->serialize($user, 'json', [
    AbstractNormalizer::GROUPS => ['api:read']
]);

5. Deserializing with Validation

Combine with Symfony’s Validator for strict deserialization:

use Symfony\Component\Validator\Validator\ValidatorInterface;

$validator = app(ValidatorInterface::class);
$errors = $validator->validate($deserializedObject);
if ($errors->count() > 0) {
    throw new \RuntimeException('Validation failed');
}

6. Handling DateTime Objects

Configure DateTimeNormalizer for consistent formatting:

use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;

$normalizers = [
    new DateTimeNormalizer(),
    new ObjectNormalizer(),
];
$serializer = new Serializer($normalizers, $encoders);

7. Partial Updates (PATCH)

Use denormalize() with partial data:

$data = ['name' => 'Updated Name'];
$user = $serializer->deserialize($data, User::class, 'array', [
    AbstractNormalizer::OBJECT_TO_POPULATE => $existingUser,
]);

Integration Tips

Laravel-Specific Patterns

  1. Service Provider Binding Bind the serializer in AppServiceProvider for global access:

    public function register()
    {
        $this->app->singleton(SerializerInterface::class, function () {
            $encoders = [new JsonEncoder()];
            $normalizers = [new ObjectNormalizer()];
            return new Serializer($normalizers, $encoders);
        });
    }
    
  2. API Resource Integration Use in Illuminate\Http\Resources\Json\JsonResource:

    public function toArray($request)
    {
        return $this->serializer->normalize($this->resource, null, [
            AbstractNormalizer::GROUPS => ['api'],
        ]);
    }
    
  3. Form Request Validation Deserialize and validate incoming requests:

    public function rules()
    {
        $data = $this->serializer->deserialize(
            $this->request->json()->all(),
            stdClass::class,
            'array'
        );
        return [
            'name' => 'required|string',
            'email' => 'required|email',
        ];
    }
    
  4. Queue Jobs Serialize payloads for delayed processing:

    $serializedData = $serializer->serialize($payload, 'json');
    dispatch(new ProcessPayloadJob($serializedData));
    

Gotchas and Tips

Pitfalls

  1. Circular References

    • Issue: Infinite loops when serializing objects with bidirectional relationships (e.g., UserPost).
    • Fix: Use circularReferenceHandler in ObjectNormalizer or implement a custom handler.
  2. Type Mismatches in Deserialization

    • Issue: Failing to deserialize due to strict type hints (e.g., int vs. string).
    • Fix: Use union types or custom normalizers to handle edge cases:
      $normalizer = new ObjectNormalizer(null, null, null, [
          'constructor_parameters' => [
              'id' => ['type' => 'int', 'default' => null],
          ],
      ]);
      
  3. Ignored Attributes

    • Issue: Sensitive fields (e.g., password) leaking into serialized output.
    • Fix: Explicitly ignore attributes:
      $normalizer = new ObjectNormalizer(null, null, null, [
          'ignoredAttributes' => ['password', 'api_token'],
      ]);
      
  4. DateTime Handling

    • Issue: Timezone inconsistencies or invalid DateTime objects.
    • Fix: Configure DateTimeNormalizer:
      $dateNormalizer = new DateTimeNormalizer('UTC');
      
  5. Partial Deserialization

    • Issue: Overwriting existing data during PATCH operations.
    • Fix: Use OBJECT_TO_POPULATE context:
      $serializer->deserialize($data, User::class, 'array', [
          AbstractNormalizer::OBJECT_TO_POPULATE => $user,
      ]);
      
  6. Custom Metadata Overrides

    • Issue: Annotations or PHPDoc types not being respected.
    • Fix: Use property_type_extractor or method_name_converter:
      $normalizer = new ObjectNormalizer(null, null, null, [
          'property_type_extractor' => new PhpDocTypeExtractor(),
      ]);
      

Debugging Tips

  1. Enable Debug Mode Set debug: true in ObjectNormalizer to log normalization issues:

    $normalizer = new ObjectNormalizer(null, null, null, ['debug' => true]);
    
  2. Inspect Normalization Groups Use AbstractNormalizer::GROUPS to debug which fields are included/excluded:

    $serializer->serialize($object, 'json', [
        AbstractNormalizer::GROUPS => ['debug:all'],
    ]);
    
  3. Check for Deprecated Methods

    • Symfony 8+ may deprecate methods like normalize() in favor of serialize()/deserialize().
    • Fix: Update to the latest version and adjust calls accordingly.
  4. Handle Undefined Properties

    • Issue: __get()/__set() magic methods causing unexpected behavior.
    • Fix: Configure ObjectNormalizer to handle magic properties:
      $normalizer = new ObjectNormalizer(null, null, null, [
          'allow_magic_properties' => true,
      ]);
      

Extension Points

  1. Custom Normalizers Implement NormalizerInterface for domain-specific logic (e.g., hashing passwords, flattening nested objects).

  2. Custom Encoders Extend EncoderInterface to support new

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport