aboutcoders/enum-serializer-bundle
Symfony bundle adding JMS Serializer support for myclabs/php-enum enums. Register enum types via config or tagged services, then serialize/deserialize to JSON using enum class names in @Type annotations or directly in serializer calls.
Install the Bundle
composer require aboutcoders/enum-serializer-bundle
Add to config/bundles.php (Symfony 4+):
return [
// ...
Abc\Bundle\EnumSerializerBundle\AbcEnumSerializerBundle::class => ['all' => true],
];
Define an Enum
Create a basic php-enum class (e.g., src/Enum/MyEnum.php):
namespace App\Enum;
use MyCLabs\Enum\Enum;
class MyEnum extends Enum
{
const OPTION_1 = 'option_1';
const OPTION_2 = 'option_2';
}
Configure Serialization
Register the enum in config/packages/abc_enum_serializer.yaml:
abc_enum_serializer:
serializer:
types:
- App\Enum\MyEnum
First Use Case Serialize/deserialize via JMS Serializer:
use JMS\Serializer\SerializerBuilder;
use JMS\Serializer\SerializerInterface;
$serializer = SerializerBuilder::create()->build();
$serialized = $serializer->serialize(new MyEnum(MyEnum::OPTION_1), 'json');
$deserialized = $serializer->deserialize($serialized, MyEnum::class, 'json');
Automatic Enum Registration
abc.enum service tag to auto-register enums (avoids manual config):
services:
App\Enum\MyEnum:
tags: ['abc.enum']
Custom Serialization Logic
Extend the bundle’s EnumHandler to modify behavior:
// src/Serializer/EnumHandler.php
use Abc\Bundle\EnumSerializerBundle\Serializer\EnumHandler as BaseEnumHandler;
class CustomEnumHandler extends BaseEnumHandler
{
public function serialize($enum, $format, array $context = [])
{
return strtoupper(parent::serialize($enum, $format, $context));
}
}
Override the handler in config:
abc_enum_serializer:
serializer:
handler: App\Serializer\CustomEnumHandler
Integration with API Platform
For API Platform projects, add the enum to serialization_groups:
use ApiPlatform\Core\Annotation\ApiResource;
use JMS\Serializer\Annotation\Groups;
#[ApiResource]
class MyEntity
{
#[Groups(['enum:serialization'])]
public MyEnum $status;
}
Dynamic Enum Loading Register enums programmatically in a compiler pass:
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class EnumCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$definition = $container->findDefinition('abc.enum_serializer.type_registry');
$definition->addMethodCall('addType', [new Reference('my_enum_service')]);
}
}
JSON-Only Support The bundle only supports JSON serialization (no XML/YAML). If you need other formats, implement a custom handler.
Case Sensitivity
Deserialization fails if the input string doesn’t match the enum’s constant name exactly (e.g., "OPTION_1" vs "option_1"). Use strtolower() or strtoupper() in custom handlers if needed.
Circular References
If enums reference each other (e.g., EnumA uses EnumB), ensure both are registered in types or tagged as services.
Deprecated AppKernel
The README shows AppKernel.php, but Symfony 4+ uses config/bundles.php. Update your config accordingly.
Check Registered Types Dump the type registry to verify enums are loaded:
$registry = $container->get('abc.enum_serializer.type_registry');
dump($registry->getTypes());
Handler Precedence If serialization behaves unexpectedly, ensure your custom handler is properly overridden in config (priority matters).
Custom Metadata Add metadata to enums for advanced serialization (e.g., labels, descriptions):
class MyEnum extends Enum
{
const OPTION_1 = ['value' => 'opt1', 'label' => 'Option One'];
}
Extend the handler to use this metadata:
public function serialize($enum, $format, array $context = [])
{
return $enum->getValue()['label'] ?? parent::serialize($enum, $format, $context);
}
Validation Combine with Symfony Validator for runtime checks:
use Symfony\Component\Validator\Constraints as Assert;
class MyEntity
{
#[Assert\Type(type: MyEnum::class)]
public MyEnum $status;
}
Performance For large-scale apps, cache the serializer instance:
$serializer = $container->get('jms_serializer');
$serializer->setCacheDir(sys_get_temp_dir()); // Enable caching
How can I help you explore Laravel packages today?