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 Pack Laravel Package

symfony/serializer-pack

Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require symfony/serializer-pack
    

    This auto-installs symfony/serializer and its dependencies (symfony/yaml, symfony/property-access, etc.).

  2. Basic Usage Register the serializer in config/services.php:

    $container->register('serializer', \Symfony\Component\Serializer\Serializer::class)
        ->setArguments([
            [new \Symfony\Component\Serializer\Encoder\JsonEncoder(), new \Symfony\Component\Serializer\Encoder\XmlEncoder()],
            [new \Symfony\Component\Serializer\Normalizer\ObjectNormalizer(), new \Symfony\Component\Serializer\Normalizer\DateTimeNormalizer()]
        ]);
    
  3. First Serialization

    $serializer = app('serializer');
    $data = $serializer->serialize($object, 'json');
    $decoded = $serializer->deserialize($data, Object::class, 'json');
    
  4. Key Files to Review

    • config/packages/serializer.yaml (auto-generated by the pack)
    • src/Serializer/ (if extending default behavior)

Implementation Patterns

Common Workflows

1. Normalization/Serialization

  • DTOs: Use ObjectNormalizer with ignoredAttributes to exclude sensitive fields:
    # config/packages/serializer.yaml
    framework:
        serializer:
            normalizers:
                App\Dto\UserDto:
                    ignored_attributes: ['password', 'apiToken']
    
  • Circular References: Enable enable_max_depth in ObjectNormalizer:
    $normalizer = new ObjectNormalizer(['enable_max_depth' => true]);
    

2. Custom Normalizers

  • Extend ObjectNormalizer for domain-specific logic:
    use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
    
    class UserNormalizer implements ContextAwareNormalizerInterface {
        public function normalize($object, $format = null, array $context = []) {
            return [
                'id' => $object->id,
                'email' => $object->email,
                'roles' => $object->getRoles()->toArray(),
            ];
        }
        // ... implement other required methods
    }
    
  • Register in serializer.yaml:
    framework:
        serializer:
            normalizers:
                App\Normalizer\UserNormalizer: ~
    

3. API Resource Integration

  • Symfony API Platform: Leverage SerializerContextBuilder to pass metadata:
    use Symfony\Component\Serializer\SerializerInterface;
    use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
    
    class CustomContextBuilder implements SerializerContextBuilderInterface {
        public function createFromRequest(Request $request, bool $normalization, array $extractedAttributes = null) {
            $context = parent::createFromRequest($request, $normalization, $extractedAttributes);
            $context['groups'] = ['api']; // Use groups for granular control
            return $context;
        }
    }
    

4. Event-Driven Serialization

  • Pre/Post Serialization Events: Use SerializerEventDispatcher:
    $dispatcher = new SerializerEventDispatcher($serializer);
    $dispatcher->addSubscriber(new class implements SerializerSubscriberInterface {
        public function onSerialize(SerializeEvent $event) {
            if ($event->getData() instanceof User) {
                $event->setData($this->sanitizeUser($event->getData()));
            }
        }
    });
    

5. Testing

  • Mock Serializer: Use SerializerInterface mock in PHPUnit:
    $mockSerializer = $this->createMock(SerializerInterface::class);
    $mockSerializer->method('serialize')->willReturn(json_encode(['id' => 1]));
    $this->app->instance(SerializerInterface::class, $mockSerializer);
    

Gotchas and Tips

Pitfalls

  1. Performance Overhead

    • Issue: Deeply nested objects or circular references can bloat memory.
    • Fix: Use enable_max_depth and max_depth in ObjectNormalizer:
      framework:
          serializer:
              normalizers:
                  Symfony\Component\Serializer\Normalizer\ObjectNormalizer:
                      max_depth: 3
      
  2. DateTime Handling

    • Issue: Default DateTimeNormalizer uses ISO format, which may not match API expectations.
    • Fix: Customize format in config:
      framework:
          serializer:
              normalizers:
                  Symfony\Component\Serializer\Normalizer\DateTimeNormalizer:
                      format: 'Y-m-d H:i:s'
      
  3. Circular References

    • Issue: Unhandled circular references throw CircularReferenceException.
    • Fix: Enable enable_max_depth or use DenormalizerInterface with custom logic.
  4. Group-Based Normalization

    • Issue: Forgetting to add @Groups({"api"}) to properties breaks group-based serialization.
    • Fix: Use PHP attributes or YAML config:
      App\Entity\User:
          attributes:
              email:
                  groups: ['api']
      
  5. Type Safety

    • Issue: Deserializing into wrong types silently fails.
    • Fix: Use denormalize() with strict type checks:
      $user = $serializer->deserialize($data, User::class, 'json', [
          'object_to_populate' => new User(), // Pre-instantiate
      ]);
      

Debugging Tips

  1. Inspect Context Use SerializerContextBuilder to log context:

    $context = $serializer->getContext();
    \Log::debug('Serialization context:', $context);
    
  2. Normalizer Debugging Enable debug mode in ObjectNormalizer:

    $normalizer = new ObjectNormalizer(['debug' => true]);
    
  3. Encoder Issues

    • JSON: Validate with json_last_error().
    • XML: Use SimpleXMLElement to validate output.

Extension Points

  1. Custom Encoders Extend EncoderInterface for formats like CSV or MessagePack:

    class CsvEncoder implements EncoderInterface {
        public function encode($data, $format, array $context = []) {
            // Custom CSV logic
        }
        public function supportsEncoding($format) { return 'csv' === $format; }
    }
    
  2. Dynamic Normalizers Use NormalizerAwareInterface for runtime normalizer selection:

    class DynamicNormalizer implements NormalizerInterface, NormalizerAwareInterface {
        public function setNormalizers(array $normalizers) {
            $this->normalizers = $normalizers;
        }
        public function normalize($object, $format = null, array $context = []) {
            // Delegate to registered normalizers
        }
    }
    
  3. Symfony Messenger Integration Serialize messages with SerializerInterface:

    $serialized = $serializer->serialize($message, 'json');
    $bus->dispatch(new AsyncMessage($serialized));
    
  4. Cache Normalization Results Use CacheNormalizer to cache serialized data:

    framework:
        serializer:
            normalizers:
                Symfony\Component\Serializer\Normalizer\CacheNormalizer:
                    cache_pool: cache.app
                    ttl: 3600
    
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware