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

jms/serializer-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require jms/serializer-bundle
    

    Add the bundle to config/bundles.php:

    return [
        // ...
        JMS\SerializerBundle\JMSSerializerBundle::class => ['all' => true],
    ];
    
  2. First Use Case: Serialize an object to JSON in a controller:

    use JMS\Serializer\SerializerInterface;
    use Symfony\Component\HttpFoundation\JsonResponse;
    
    public function show(SerializerInterface $serializer, $id)
    {
        $entity = $this->entityManager->find(Entity::class, $id);
        $json = $serializer->serialize($entity, 'json');
        return new JsonResponse($json, 200, [], true);
    }
    
  3. Where to Look First:

    • Official Documentation (focus on "Usage" and "Configuration" sections).
    • config/packages/jms_serializer.yaml (auto-generated; customize as needed).
    • src/Serializer/ directory (for custom serializers/normalizers).

Implementation Patterns

Core Workflows

  1. Serialization/Deserialization:

    // Serialize
    $serializer->serialize($data, 'json'); // 'xml', 'yaml', etc.
    
    // Deserialize
    $deserialized = $serializer->deserialize($json, Entity::class, 'json');
    
  2. Type-Specific Handling:

    • Use metadata (@Serializer\Type, @Serializer\ExclusionPolicy) for fine-grained control:
      use JMS\Serializer\Annotation as Serializer;
      
      class User
      {
          /** @Serializer\Type("string") */
          public $uuid;
      
          /** @Serializer\ExclusionPolicy("all") */
          public $password;
      }
      
  3. API Responses:

    • Group fields for different contexts (e.g., public, admin):
      # config/packages/jms_serializer.yaml
      jms_serializer:
          metadata:
              directories:
                  FOSUserBundle
                  App
      
      // In a normalizer
      $context['groups'] = ['public'];
      
  4. Event Listeners:

    • Hook into serializer.pre_serialize/serializer.post_deserialize:
      public function onPreSerialize(PreSerializeEvent $event)
      {
          $data = $event->getData();
          $data->setSerializedAt(new \DateTime()); // Add dynamic fields
      }
      
  5. Custom Normalizers:

    • Extend JMS\Serializer\Normalizer\AbstractNormalizer for complex types:
      class DateTimeNormalizer extends AbstractNormalizer
      {
          public function normalize($object, $format, array $context = [])
          {
              return $object->format(\DateTime::ATOM);
          }
      }
      
    • Register in services.yaml:
      services:
          App\Serializer\Normalizer\DateTimeNormalizer:
              tags: [jms_serializer.normalizer]
      

Integration Tips

  1. Symfony Forms:

    • Use JMS\Serializer\Handler\HandlerRegistry to transform form data:
      $handler = $serializer->getHandlerRegistry();
      $handler->registerSubscribingHandler(new MyCustomHandler());
      
  2. Doctrine Integration:

    • Serialize entities with associations:
      $serializer->serialize($entity, 'json', [
          'groups' => ['default', 'associations'],
      ]);
      
  3. API Platform:

    • Override default serialization with custom normalizers or metadata.
  4. Messaging (e.g., Symfony Messenger):

    • Serialize messages for transport:
      $serialized = $serializer->serialize($message, 'json');
      
  5. Caching:

    • Cache serialized output for performance:
      $cacheKey = md5($serializedData);
      $cached = $cache->get($cacheKey, function() use ($serializer, $data) {
          return $serializer->serialize($data, 'json');
      });
      

Gotchas and Tips

Pitfalls

  1. Circular References:

    • Default behavior throws CircularReferenceException. Use max_depth or custom handlers:
      $serializer->serialize($data, 'json', ['max_depth' => 2]);
      
    • Or implement JMS\Serializer\ContextBuilderInterface to handle cycles.
  2. Metadata Conflicts:

    • Annotations/YAML/XML metadata can override each other. Explicitly define priorities:
      # config/packages/jms_serializer.yaml
      jms_serializer:
          metadata:
              directories:
                  App
                  FOSUserBundle  # Lower priority
      
  3. Performance:

    • Avoid serializing large collections without pagination or max_depth.
    • Use JMS\Serializer\SerializationContext to limit fields dynamically:
      $context = new SerializationContext();
      $context->setGroups(['light']);
      
  4. Deserialization Security:

    • Validate deserialized data to prevent object injection:
      $deserialized = $serializer->deserialize($json, Entity::class, 'json', [
          'object_to_populate' => new Entity(), // Safe default
      ]);
      
  5. Doctrine Proxy Issues:

    • Serializing Doctrine proxies may fail. Use LazyLoadingException handling:
      try {
          $serializer->serialize($proxy, 'json');
      } catch (\Doctrine\ORM\PersistentCollection::class $e) {
          // Initialize collections first
      }
      

Debugging

  1. Enable Debug Mode:

    • Set JMS_SERIALIZER_DEBUG env var to log metadata and serialization steps.
  2. Check Metadata:

    • Dump metadata for an object:
      $metadataFactory = $serializer->getMetadataFactory();
      $metadata = $metadataFactory->getMetadataFor(get_class($object));
      var_dump($metadata);
      
  3. Common Errors:

    • "No serializer found": Ensure the target class has a normalizer or metadata.
    • "Invalid type": Verify @Serializer\Type annotations or YAML config.
    • Empty output: Check ExclusionPolicy or groups filters.

Extension Points

  1. Custom Serialization Formats:

    • Implement JMS\Serializer\SerializerBuilderInterface for new formats (e.g., MessagePack).
  2. Dynamic Metadata:

    • Use JMS\Serializer\Metadata\StaticPropertyMetadataFactory to generate metadata at runtime.
  3. Event Dispatching:

    • Extend JMS\Serializer\EventDispatcher\EventDispatcher to add custom events.
  4. Performance Optimization:

    • Cache metadata with JMS\Serializer\Metadata\MetadataFactoryInterface:
      jms_serializer:
          metadata:
              cache: apcu
      
  5. Testing:

    • Mock SerializerInterface in tests:
      $serializer = $this->createMock(SerializerInterface::class);
      $serializer->method('serialize')->willReturn('{"test":true}');
      
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