fitbug/symfony-yaml-serializer-encoder-decoder
Adds YAML encoding/decoding support to Symfony’s Serializer component. Install via Composer and register YamlEncoder with YamlEncode/YamlDecode to serialize objects to/from YAML alongside your normalizers. Requires PHP 5.6+.
composer require fitbug/symfony-yaml-serializer-encoder-decoder
// app/Providers/AppServiceProvider.php
use Symfony\Component\Serializer\Serializer;
use Fitbug\SymfonyYamlSerializerEncoderDecoder\YamlEncoder;
use Symfony\Component\Yaml\Yaml;
public function register()
{
$this->app->singleton('yaml.serializer', function () {
$encoders = [new YamlEncoder(new Yaml(), new Yaml())];
$normalizers = \Symfony\Component\Serializer\Normalizer\NormalizerFactory::create();
return new Serializer($normalizers, $encoders);
});
}
use Illuminate\Support\Facades\Facade;
class ExampleController extends Controller
{
public function serializeYaml()
{
$serializer = app('yaml.serializer');
$data = ['name' => 'John', 'roles' => ['admin']];
// Encode to YAML
$yaml = $serializer->encode($data, 'yaml');
dd($yaml);
// Decode from YAML
$decoded = $serializer->decode($yaml, 'yaml');
dd($decoded);
}
}
YamlEncoder (core class).Serializer service binding and facade patterns.// Encode PHP object/array to YAML
$yaml = app('yaml.serializer')->encode($arrayOrObject, 'yaml');
// Decode YAML to PHP object
$object = app('yaml.serializer')->decode($yaml, 'yaml', \stdClass::class);
Use normalizers to convert Eloquent models to/from YAML:
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
$normalizers = [
new ObjectNormalizer(),
// Add custom normalizers for model-specific logic
];
$serializer = new Serializer($normalizers, [new YamlEncoder(new Yaml(), new Yaml())]);
// Serialize a User model
$user = User::first();
$yaml = $serializer->encode($user, 'yaml');
Load YAML configs dynamically (e.g., feature flags, API specs):
// Load YAML from file
$yamlContent = file_get_contents(storage_path('config/api_spec.yaml'));
$spec = app('yaml.serializer')->decode($yamlContent, 'yaml', \stdClass::class);
// Update config and re-serialize
$spec->version = '2.0';
file_put_contents(storage_path('config/api_spec.yaml'), app('yaml.serializer')->encode($spec, 'yaml'));
Normalize API responses to YAML for logging/auditing:
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
$normalizers = [
new ObjectNormalizer(),
new DateTimeNormalizer(),
];
$serializer = new Serializer($normalizers, [new YamlEncoder(new Yaml(), new Yaml())]);
// Log API response as YAML
$responseYaml = $serializer->encode($apiResponse, 'yaml');
Log::info('API Response', ['yaml' => $responseYaml]);
Create a reusable facade for cleaner syntax:
// app/Facades/YamlSerializer.php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class YamlSerializer extends Facade
{
protected static function getFacadeAccessor() { return 'yaml.serializer'; }
}
Usage:
use App\Facades\YamlSerializer;
$yaml = YamlSerializer::encode($data, 'yaml');
Process YAML files via CLI:
// app/Console/Commands/ProcessYamlConfig.php
use App\Facades\YamlSerializer;
class ProcessYamlConfig extends Command
{
public function handle()
{
$yaml = file_get_contents($this->argument('file'));
$data = YamlSerializer::decode($yaml, 'yaml');
// Process $data...
}
}
Validate/transform YAML payloads in incoming requests:
// app/Http/Middleware/ValidateYamlPayload.php
public function handle($request, Closure $next)
{
if ($request->isYamlPayload()) {
$data = YamlSerializer::decode($request->getContent(), 'yaml');
$request->merge($data);
}
return $next($request);
}
Combine with Symfony Normalizers:
ObjectNormalizer for Eloquent models.DateTimeNormalizer for datetime fields.$normalizers = [
new ObjectNormalizer(null, null, null, new \DateTimeZone('UTC')),
new DateTimeNormalizer(),
];
Handle Circular References:
Symfony’s ObjectNormalizer supports circular references via enableMaxDepth:
new ObjectNormalizer(null, null, null, null, null, null, ['enableMaxDepth' => true])
Custom Normalizers:
Extend functionality for Laravel-specific types (e.g., Carbon, Collection):
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
class CarbonNormalizer implements NormalizerInterface
{
public function normalize($object, $format = null, array $context = [])
{
return $object->toDateTimeString();
}
// ... other methods
}
Error Handling: Wrap serialization in try-catch blocks:
try {
$yaml = YamlSerializer::encode($data, 'yaml');
} catch (\Symfony\Component\Serializer\Exception\ExceptionInterface $e) {
Log::error('YAML serialization failed', ['error' => $e->getMessage()]);
throw new \RuntimeException('Invalid YAML data', 0, $e);
}
Performance:
Reuse the Serializer instance (Laravel’s service container caches it) instead of creating new instances per request.
PHP Version Mismatch:
return_type declarations).symfony/yaml directly with Symfony Serializer v6+.YAML Parsing Quirks:
items: [1, 2,]). Fix: Pre-process YAML or use symfony/yaml directly.&anchor) may not work as expected. Tip: Validate YAML with symfony/yaml first.Namespace Collisions:
Serializer and Laravel’s Serializer (if any) may conflict. Solution:
\Symfony\Component\Serializer\Serializer).SerializerServiceProvider.Stale Dependencies:
symfony/yaml:3.x). Risk: Security updates or BC breaks. Mitigation:
composer.json.Laravel Cache Conflicts:
symfony/yaml for caching (e.g., Cache::put()), ensure the YAML encoder/decoder aligns with Laravel’s cache drivers.Normalizer Conflicts:
Arrayable/Jsonable with Symfony’s normalizers may cause unexpected behavior. Tip: Use ObjectNormalizer with ignoredAttributes to exclude Laravel-specific methods.symfony/yaml to pre-validate YAML before serialization:
use Symfony\Component\Yaml\Yaml as SymfonyYaml;
$yaml = file_get_contents('config.yaml');
SymfonyYaml::parse($yaml); // Throws exception on invalid YAML
How can I help you explore Laravel packages today?