una programacion hacer funciones funcion estructuras estructura ejercicios con como clases ats anidar anidadas anidada php json symfony denormalization

php - programacion - funcion anidada c++



Desnormalizar la estructura anidada en objetos con el serializador Symfony 2 (2)

Estoy trabajando en el proyecto Symfony 2 con la versión 2.8 y estoy usando el componente integrado Serializer -> http://symfony.com/doc/current/components/serializer.html

Tengo una estructura JSON proporcionada por un servicio web. Después de la deserialización, quiero desnormalizar mi contenido en objetos. Aquí está mi estructura (modelo / marca en un contexto de aplicación de automóvil).

[{ "0": { "id": 0, "code": 1, "model": "modelA", "make": { "id": 0, "code": 1, "name": "makeA" } } } , { "1": { "id": 1, "code": 2, "model": "modelB", "make": { "id": 0, "code": 1, "name": "makeA" } } }]

Mi idea es llenar un objeto VehicleModel que contiene una referencia a un objeto VehicleMake .

class VehicleModel { public $id; public $code; public $model; public $make; // VehicleMake }

Esto es lo que hago:

// Retrieve data in JSON $data = ... $serializer = new Serializer([new ObjectNormalizer(), new ArrayDenormalizer()], [new JsonEncoder()]); $models = $serializer->deserialize($data, ''/Namespace/VehicleModel[]'', ''json'');

Como resultado, mi objeto VehicleModel está correctamente rellenado, pero $make es lógicamente una matriz clave / valor. Aquí quiero un VehicleMake lugar.

Hay una manera de hacer eso ?

Gracias


ObjectNormalizer necesita más configuración. Al menos deberá proporcionar el cuarto parámetro de tipo PropertyTypeExtractorInterface .

Aquí hay un ejemplo (algo hacky):

<?php use Symfony/Component/PropertyInfo/PropertyTypeExtractorInterface; use Symfony/Component/PropertyInfo/Type; use Symfony/Component/Serializer/Encoder/JsonEncoder; use Symfony/Component/Serializer/Normalizer/ArrayDenormalizer; use Symfony/Component/Serializer/Normalizer/ObjectNormalizer; use Symfony/Component/Serializer/Serializer; $a = new VehicleModel(); $a->id = 0; $a->code = 1; $a->model = ''modalA''; $a->make = new VehicleMake(); $a->make->id = 0; $a->make->code = 1; $a->make->name = ''makeA''; $b = new VehicleModel(); $b->id = 1; $b->code = 2; $b->model = ''modelB''; $b->make = new VehicleMake(); $b->make->id = 0; $b->make->code = 1; $b->make->name = ''makeA''; $data = [$a, $b]; $serializer = new Serializer( [new ObjectNormalizer(null, null, null, new class implements PropertyTypeExtractorInterface { /** * {@inheritdoc} */ public function getTypes($class, $property, array $context = array()) { if (!is_a($class, VehicleModel::class, true)) { return null; } if (''make'' !== $property) { return null; } return [ new Type(Type::BUILTIN_TYPE_OBJECT, true, VehicleMake::class) ]; } }), new ArrayDenormalizer()], [new JsonEncoder()] ); $json = $serializer->serialize($data, ''json''); print_r($json); $models = $serializer->deserialize($json, VehicleModel::class . ''[]'', ''json''); print_r($models);

Tenga en cuenta que en su ejemplo json, la primera entrada tiene una matriz como valor para make . Tomé esto como un error tipográfico, si es deliberado, por favor deje un comentario.

Para que esto sea más automático, es posible que desee experimentar con PhpDocExtractor .


En los casos en que necesitas más flexibilidad en la desnormalización, es bueno crear tus propios denormalizadores.

$serializer = new Serializer( [ new ArrayNormalizer(), new VehicleDenormalizer(), new VehicleMakeDenormalizer() ], [ new JsonEncoder() ] ); $models = $serializer->deserialize( $data, ''/Namespace/VehicleModel[]'', ''json'' );

Aquí el código aproximado de tal denormalizador

class VehicleDenormalizer implements DenormalizerInterface, DenormalizerAwareInterface { public function denormalize($data, $class, $format, $context) { $vehicle = new VehicleModel(); ... $vehicleMake = $this->denormalizer->denormalize( $data->make, VehicleMake::class, $format, $context ); $vehicle->setMake($vehicleMake); ... } }

Solo tengo dudas sobre si debemos confiar en $this->denormalizer->denormalize (que funciona correctamente solo porque usamos Symfony/Component/Serializer/Serializer ) o debemos inyectar de forma explícita VehicleMakeDenormalizer en VehicleDenormalizer

$vehicleDenormalizer = new VehicleDenormalizer(); $vehicleDenormalizer->setVehicleMakeDenormalizer(new VehicleMakeDenormalizer());