Installation:
composer require jms/serializer-bundle
Add the bundle to config/bundles.php:
return [
// ...
JMS\SerializerBundle\JMSSerializerBundle::class => ['all' => true],
];
First Use Case: Serialize an object to JSON in a controller:
use JMS\Serializer\SerializerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
class MyController extends AbstractController
{
public function serializeObject(SerializerInterface $serializer, MyComplexObject $object): JsonResponse
{
$json = $serializer->serialize($object, 'json');
return new JsonResponse($json, 200, [], true);
}
}
Where to Look First:
config/packages/jms_serializer.yaml (default configuration).src/Serializer/ directory (if you need custom serializers/handlers).Serialization/Deserialization:
// Serialize
$serializer->serialize($data, 'json'); // or 'xml', 'yaml', etc.
// Deserialize
$deserialized = $serializer->deserialize($json, MyClass::class, 'json');
Type-Specific Handling:
Use annotations (@Serializer\ExclusionPolicy, @Serializer\Type) or YAML/XML configurations to control serialization behavior:
# config/packages/jms_serializer.yaml
jms_serializer:
metadata:
directories:
MyApp:
namespace_prefix: "App\\"
path: "%kernel.project_dir%/config/serializer"
Custom Serializers/Handlers:
Extend JMS\Serializer\Context or create custom handlers:
use JMS\Serializer\Handler\SubscribingHandlerInterface;
class CustomHandler implements SubscribingHandlerInterface
{
public static function getSubscribingMethods()
{
return [
[
'direction' => SerializationDirection::DESERIALIZATION,
'format' => 'json',
'type' => 'App\Entity\MyEntity',
'method' => 'deserializeMyEntity',
],
];
}
public function deserializeMyEntity(DeserializationContext $context)
{
// Custom logic
}
}
Register in services.yaml:
services:
App\Serializer\CustomHandler:
tags: [jms_serializer.subscribing_handler]
API Integration:
Use with Symfony’s SerializerAwareTrait or inject SerializerInterface into services:
use JMS\Serializer\SerializerInterface;
class MyService
{
public function __construct(private SerializerInterface $serializer) {}
public function transformData($data): string
{
return $this->serializer->serialize($data, 'json');
}
}
Event Listeners:
Hook into serializer.event_dispatcher to modify serialization dynamically:
use JMS\Serializer\EventDispatcher\EventDispatcher;
use JMS\Serializer\EventDispatcher\ObjectEvent;
class MyListener
{
public function onPreSerialize(ObjectEvent $event)
{
$event->getObject()->setProperty('modified', true);
}
}
Register in services.yaml:
services:
App\Serializer\MyListener:
tags:
- { name: kernel.event_listener, event: serializer.event_dispatcher, method: onPreSerialize }
Circular References:
By default, the serializer throws an exception on circular references. Configure circular_reference_handler in jms_serializer.yaml:
jms_serializer:
handlers:
datetime: false
circular_reference_handler: set # or 'ignore', 'exception'
Metadata Caching:
Metadata is cached by default in var/cache/dev/jms_serializer. Clear cache after adding new annotations or YAML configs:
php bin/console cache:clear
Annotation vs. YAML:
@Serializer\*) are processed at runtime and can slow down serialization.Deprecated Methods:
Avoid JMS\Serializer\Serializer (deprecated). Use SerializerInterface or SerializerBuilder instead.
Symfony 5+ Compatibility:
The bundle is compatible with Symfony 5/6, but some older features (e.g., SerializerAwareInterface) may require adjustments.
Enable Debug Mode:
Set debug: true in jms_serializer.yaml to log metadata generation:
jms_serializer:
debug: true
Inspect Metadata: Dump metadata for a class:
$metadataFactory = $serializer->getMetadataFactory();
$metadata = $metadataFactory->getMetadataFor('App\Entity\MyEntity');
dump($metadata);
Common Errors:
JMS\Serializer\SerializationContext.'json', 'xml') matches a registered handler.Custom Formats:
Register new formats via serializer.format_handlers:
services:
app.custom_serializer:
class: App\Serializer\CustomSerializer
tags: [jms_serializer.format_handler, jms_serializer.format_handler_name: 'custom']
Metadata Customization: Override metadata directories or factories:
jms_serializer:
metadata:
directories:
MyApp:
path: "%kernel.project_dir%/config/serializer"
namespace_prefix: "App\\"
cache: false # Disable caching for development
Performance Optimization:
SerializerBuilder to pre-configure the serializer with handlers/contexts.datetime, dateinterval) in jms_serializer.yaml.Testing:
Mock SerializerInterface in tests:
$serializer = $this->createMock(SerializerInterface::class);
$serializer->method('serialize')->willReturn('{"data":"test"}');
How can I help you explore Laravel packages today?