wayofdev/laravel-symfony-serializer
Installation
composer require wayofdev/laravel-symfony-serializer
Publish the config (optional):
php artisan vendor:publish --provider="WayOfDev\LaravelSymfonySerializer\LaravelSymfonySerializerServiceProvider"
First Use Case: Serializing a Model
use WayOfDev\LaravelSymfonySerializer\Facades\Serializer;
$user = User::find(1);
$serialized = Serializer::serialize($user, 'json');
$deserialized = Serializer::deserialize($serialized, User::class, 'json');
Where to Look First
WayOfDev\LaravelSymfonySerializer\Facades\Serializer (primary entry point).config/symfony-serializer.php (for customizing encoders/normalizers).Model Serialization/Deserialization
// Serialize to JSON
$json = Serializer::serialize($model, 'json');
// Deserialize from JSON
$model = Serializer::deserialize($json, Model::class, 'json');
Custom Normalizers
Extend Symfony\Component\Serializer\Normalizer\NormalizerInterface and register via config:
'normalizers' => [
App\Normalizers\CustomNormalizer::class,
],
API Response Handling
return response()->json(
Serializer::serialize($collection, 'json', [
'groups' => ['api']
])
);
Event-Driven Serialization
Use Serializer::serializeToStream() for large objects (e.g., exporting CSV/Excel):
$stream = Serializer::serializeToStream($data, 'csv');
return response()->stream(fn() => $stream, 200, [
'Content-Type' => 'text/csv',
'Content-Disposition' => 'attachment; filename="export.csv"',
]);
Integration with Laravel Events
use WayOfDev\LaravelSymfonySerializer\Events\Serializing;
Serializing::dispatch($model, 'json')->then(function ($serialized) {
// Post-serialization logic
});
@Groups annotations (via serializer:groups config) for granular control over serialized fields.CacheNormalizer for performance-critical paths:
'normalizers' => [
Symfony\Component\Serializer\Normalizer\CacheNormalizer::class,
],
$data = Serializer::deserialize($json, stdClass::class, 'json');
Validator::make($data, ['field' => 'required'])->validate();
Circular References
CircularReferenceException. Use ignore_circular_references config option or implement DenormalizerInterface:
'context' => [
'ignore_circular_references' => true,
],
Type Safety
'denormalizers' => [
App\Denormalizers\AbstractClassDenormalizer::class,
],
Performance Overhead
Serializer::serialize() with stream context for memory efficiency:
Serializer::serialize($collection, 'json', ['stream' => true]);
Config Overrides
config/symfony-serializer.php) is merged with defaults. Overrides may silently fail if syntax is incorrect. Validate with:
php artisan config:clear
Serializer::setDebug(true); // Logs normalization/denormalization steps
Serializer::getContext() to debug serialization/deserialization context:
$context = Serializer::getContext();
dd($context['groups'], $context['attributes']);
Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface to log normalization steps:
public function normalize($object, string $format = null, array $context = [])
{
\Log::debug('Normalizing: ' . get_class($object));
return parent::normalize($object, $format, $context);
}
Custom Encoders Register new encoders (e.g., XML, YAML) in the config:
'encoders' => [
Symfony\Component\Serializer\Encoder\XmlEncoder::class,
],
Event Listeners
Subscribe to Serializing/Deserializing events for pre/post-processing:
Serializing::listen(function ($event) {
$event->getData()->append('custom_field', 'value');
});
Service Provider Binding Bind custom serializers to the container:
$this->app->bind(
Symfony\Component\Serializer\SerializerInterface::class,
App\CustomSerializer::class
);
Testing
Mock the Serializer facade in tests:
$this->app->instance(
WayOfDev\LaravelSymfonySerializer\Facades\Serializer::class,
Mockery::mock(Symfony\Component\Serializer\SerializerInterface::class)
);
How can I help you explore Laravel packages today?