class ContragentDto
{
/**
* @var Phone[]
*/
private $phones = [];
/**
* @return Phone[]
*/
public function getPhones(): array
{
return $this->phones;
}
/**
* @param Phone[] $phones
*/
public function setPhones(array $phones): void
{
$this->phones = $phones;
}
}
$normalizer = new ObjectNormalizer(null, null, null, new ReflectionExtractor());
$serializer = new Serializer([$normalizer]);
return $serializer->denormalize($array, ContragentDto::class);
{
"uuid": "00004539-73d6-4211-8a32-913bd34f3c8b",
"phones": [
{
"id": 6082892,
"type": "mob",
"number": "+79818"
},
{
"id": 60828927,
"type": "mob",
"number": "+7988"
}
],
}';
$reflectionExtractor = new ReflectionExtractor();
$phpDocExtractor = new PhpDocExtractor();
$propertyTypeExtractor = new PropertyInfoExtractor([$reflectionExtractor], [$phpDocExtractor, $reflectionExtractor], [$phpDocExtractor], [$reflectionExtractor], [$reflectionExtractor]);
$normalizer = new ObjectNormalizer(null, null, null, $propertyTypeExtractor);
$arrayNormalizer = new ArrayDenormalizer();
$serializer = new Serializer([$arrayNormalizer, $normalizer]);
return $serializer->denormalize($array, ContragentDto::class);
class PhoneNormalizer implements NormalizerInterface, DenormalizerInterface
{
/**
* @inheritDoc
*/
public function denormalize($data, $type, $format = null, array $context = [])
{
$phone = new Phone();
$phone->id = $data['id'];
$phone->type = $data['type'];
$phone->number = $data['number'];
return $phone;
}
/**
* @inheritDoc
*/
public function supportsDenormalization($data, $type, $format = null)
{
return $type === Phone::class;
}
/**
* @inheritDoc
*/
public function normalize($object, $format = null, array $context = [])
{
return [
'id' => $object->id,
'type' => $object->type,
'number' => $object->number,
];
}
/**
* @inheritDoc
*/
public function supportsNormalization($data, $format = null)
{
return $data instanceof Phone;
}
}
Performance¶
To figure which normalizer (or denormalizer) must be used to handle an object, the Serializer class will call the supportsNormalization() (or supportsDenormalization()) of all registered normalizers (or denormalizers) in a loop.
The result of these methods can vary depending on the object to serialize, the format and the context. That's why the result is not cached by default and can result in a significant performance bottleneck.
However, most normalizers (and denormalizers) always return the same result when the object's type and the format are the same, so the result can be cached. To do so, make those normalizers (and denormalizers) implement the CacheableSupportsMethodInterface and return true when hasCacheableSupportsMethod() is called.
Запустил у себя все на реальных примерах и обрабатывает по 8 секунд.
В реальной жизни вложенность классов на много больше + данных тоже очень много.
ObjectNormalizer
$array = уже готовый массив с данными.
className = название класса
$reflectionExtractor = new ReflectionExtractor();
$phpDocExtractor = new PhpDocExtractor();
$propertyTypeExtractor = new PropertyInfoExtractor(
[$reflectionExtractor],
[$phpDocExtractor, $reflectionExtractor],
[$phpDocExtractor],
[$reflectionExtractor],
[$reflectionExtractor]
);
$normalizer = new ObjectNormalizer(
null,
null,
null,
$propertyTypeExtractor
);
$arrayNormalizer = new ArrayDenormalizer();
$serializer = new Serializer([$arrayNormalizer, $normalizer]);
return $serializer->denormalize($array, $className);
$normalizer = new ObjectNormalizer(
null,
null,
null,
new ReflectionExtractor()
);
$arrayNormalizer = new ArrayDenormalizer();
$serializer = new Serializer([$arrayNormalizer, $normalizer]);
return $serializer->denormalize($array, $className);
$reflectionExtractor = new ReflectionExtractor();
$phpDocExtractor = new PhpDocExtractor();
$propertyTypeExtractor = new PropertyInfoExtractor(
[$reflectionExtractor],
[$phpDocExtractor, $reflectionExtractor],
[$phpDocExtractor],
[$reflectionExtractor],
[$reflectionExtractor]
);
$classMetadataFactory = new CacheClassMetadataFactory(
new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())),
new ApcuAdapter('SymfonyMetadata')
);
$propertyAccessor = PropertyAccess::createPropertyAccessorBuilder()
->setCacheItemPool(new ApcuAdapter('SymfonyPropertyAccessor'))
->getPropertyAccessor();
$propertyTypeExtractor = new PropertyInfoCacheExtractor($propertyTypeExtractor, $cacheItemPool);
$classMetadataFactory = new CacheClassMetadataFactory(
new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())),
new ApcuAdapter('SymfonyMetadata')
);
$propertyAccessor = PropertyAccess::createPropertyAccessorBuilder()
->setCacheItemPool(new ApcuAdapter('SymfonyPropertyAccessor'))
->getPropertyAccessor();
$reflectionExtractor = new ReflectionExtractor();
$phpDocExtractor = new PhpDocExtractor();
$propertyTypeExtractor = new PropertyInfoExtractor(
[$reflectionExtractor],
[$phpDocExtractor, $reflectionExtractor],
[$phpDocExtractor],
[$reflectionExtractor],
[$reflectionExtractor]
);
$propertyTypeExtractor = new PropertyInfoCacheExtractor($propertyTypeExtractor, new ApcuAdapter('SymfonyPropertyAccessor'));
$normalizer = new ObjectNormalizer(
$classMetadataFactory,
null,
$propertyAccessor,
$propertyTypeExtractor
);
$arrayNormalizer = new ArrayDenormalizer();
$serializer = new Serializer([$arrayNormalizer, $normalizer]);
return $serializer->denormalize($array, $className);