symfony/serializer
Symfony Serializer component for converting object graphs and data structures to/from arrays and formats like JSON or XML. Supports powerful normalizers/encoders, metadata, naming and type handling—ideal for APIs, messaging, and data interchange.
## Getting Started
### Minimal Setup in Laravel
1. **Installation**:
```bash
composer require symfony/serializer:^8.1
No additional configuration is needed for basic usage, but ensure compatibility with Symfony 8.1+ components.
First Use Case: Serialize an Eloquent model to JSON with improved error handling:
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
$encoders = [new JsonEncoder()];
$normalizers = [new ObjectNormalizer()];
$serializer = new Serializer($normalizers, $encoders);
$user = User::find(1);
try {
$json = $serializer->serialize($user, 'json');
} catch (\Symfony\Component\Serializer\Exception\ExceptionInterface $e) {
report($e); // Laravel's error reporting
$json = json_encode(['error' => 'Serialization failed']);
}
Where to Look First:
src/Serializer.php (core class)src/Normalizer/ (for custom normalizers)ExceptionInterface improvements in Exception/ directory for better error handling.// Serialize with improved error handling
$serializer->serialize($object, 'json');
// Deserialize with explicit type hints
$deserialized = $serializer->deserialize($json, User::class, 'json');
Extend ObjectNormalizer with Symfony 8.1's new NormalizerAwareInterface if needed:
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
class EloquentNormalizer extends ObjectNormalizer implements NormalizerAwareInterface
{
use NormalizerAwareInterface;
public function normalize($object, string $format = null, array $context = [])
{
if ($object instanceof Model) {
return [
'id' => $object->getKey(),
'attributes' => $object->getAttributes(),
'relations' => $object->relations,
];
}
return parent::normalize($object, $format, $context);
}
}
Use @Groups annotations while checking for deprecation warnings:
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Annotation\Deprecated;
class User
{
#[Groups(['api'])]
public string $name;
#[Deprecated('Use email_address instead')]
#[Groups(['admin'])]
public string $email;
}
Deserialize with stricter type checking:
$data = json_decode($request->getContent(), true);
$user = $serializer->deserialize($data, User::class, 'json', [
AbstractNormalizer::IGNORED_ATTRIBUTES => ['password'], // Explicitly ignore
]);
Enable circular reference handling with enhanced debugging:
$normalizers = [new ObjectNormalizer([], null, null, [
'circular_reference_handler' => function ($object) {
return $object->getId();
},
'debug' => true, // New in v8.1 for better error reporting
])];
Use Symfony\Component\HttpFoundation\Response with updated headers:
$response = new Response($serializer->serialize($data, 'json'));
$response->headers->set('Content-Type', 'application/json');
$response->headers->set('X-Content-Type-Options', 'nosniff'); // Security best practice
Register the serializer with improved dependency injection:
public function register()
{
$this->app->singleton(SerializerInterface::class, function ($app) {
$encoders = [new JsonEncoder()];
$normalizers = [
new ObjectNormalizer(null, null, null, [
'debug' => $app->isLocal(), // Enable debug only in local env
]),
new EloquentNormalizer(),
];
return new Serializer($normalizers, $encoders);
});
}
Extend JsonResource with explicit serialization groups:
use Illuminate\Http\Resources\Json\JsonResource;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Serializer\Annotation\Groups;
class UserResource extends JsonResource
{
public function toArray($request)
{
$serializer = app(SerializerInterface::class);
return $serializer->normalize($this->resource, null, [
AbstractNormalizer::GROUPS => ['api'],
AbstractNormalizer::IGNORED_ATTRIBUTES => ['pivot'], // Explicitly ignore
]);
}
}
Deserialize and validate with Symfony 8.1's improved validation integration:
public function rules()
{
$data = $this->serializer->deserialize($this->request->getContent(), stdClass::class, 'json');
return [
'name' => 'required|string|max:255',
'email' => 'required|email|max:255',
];
}
public function failedValidation(\Illuminate\Contracts\Validation\Validator $validator)
{
throw new \Symfony\Component\Serializer\Exception\ValidationFailedException(
$validator->errors()->toArray()
);
}
Deprecated Methods in v8.1
normalize() in ObjectNormalizer may trigger deprecation warnings.SerializerInterface methods directly or update custom normalizers:
// Old (deprecated)
$normalizer->normalize($object);
// New (recommended)
$serializer->serialize($object, 'json');
Improved Error Reporting (Bug #64296)
ExceptionHandler is configured to log these:
try {
$serializer->serialize($object, 'json');
} catch (\Symfony\Component\Serializer\Exception\ExceptionInterface $e) {
report($e); // Laravel's error reporting
}
Type Mismatches with Stricter Validation
allow_extra_attributes and ignore_unknown_properties:
new ObjectNormalizer(null, null, null, [
'ignore_unknown_properties' => true,
'allow_extra_attributes' => false, // Default is now stricter
]);
Circular References Without Handler
circular_reference_handler with debug mode:
new ObjectNormalizer(null, null, null, [
'circular_reference_handler' => function ($object) {
return $object->getKey();
},
'debug' => true,
]);
Groups and Wildcards (Deprecation Warning)
*) may trigger deprecation warnings.#[Groups(['user:read'])]
public string $name;
Timezone Handling in DateTimeNormalizer
new DateTimeNormalizer('UTC');
Enable Debug Mode for Normalizers
Set debug: true in ObjectNormalizer for detailed error messages:
new ObjectNormalizer(null, null, null, ['debug' => true]);
Inspect Normalization Context with Enhanced Logging Pass a context array and log it for debugging:
$context = [
AbstractNormalizer::GROUPS => ['api'],
'debug' => true,
];
$serializer->serialize($object, 'json', $context);
How can I help you explore Laravel packages today?