wyl*_*jon 3 serialization deserialization symfony-3.4
我使用了 Symfony 序列化器来序列化我的Recherche对象。在一个Recherche对象中,我有子对象 :Categorie和Lieu。
当我反序列化我的Recherche对象时,所有子对象都被转换成数组。我希望它们再次成为对象。
这就是我序列化对象的方式:
$encoders = array(new JsonEncoder());
$normalizer = new ObjectNormalizer();
$normalizer->setIgnoredAttributes(array('parent', 'enfants'));
$normalizer->setCircularReferenceHandler(function ($object) {
return $object->getCode();
});
$normalizers = array($normalizer);
$serializer = new Serializer($normalizers, $encoders);
$rechercheJson= $serializer->serialize($recherche, 'json');
Run Code Online (Sandbox Code Playgroud)
这就是我反序列化它的方式:
$encoders = array(new JsonEncoder());
$normalizer = new ObjectNormalizer();
$normalizer->setIgnoredAttributes(array('parent', 'enfants'));
$normalizer->setCircularReferenceHandler(function ($object) {
return $object->getCode();
});
$normalizers = array($normalizer);
$serializer = new Serializer($normalizers, $encoders);
$recherche = $serializer->deserialize($recherche_json, Recherche::class, 'json');
Run Code Online (Sandbox Code Playgroud)
我认为可能与规范化器有关,但我在文档中找不到任何对我有帮助的内容。
任何人都有帮助的想法?
谢谢 !
编辑:看到这篇文章后:使用 symfony 2 序列化程序对对象中的嵌套结构进行非规范化
我试过这个:
$encoders = array(new JsonEncoder());
$normalizer = new ObjectNormalizer(null, null, null, new SerializationPropertyTypeExtractor());
$normalizer->setIgnoredAttributes(array('parent', 'enfants'));
$normalizer->setCircularReferenceHandler(function ($object) {
return $object->getCode();
});
$normalizers = array($normalizer, new ArrayDenormalizer());
$serializer = new Serializer($normalizers, $encoders);
$recherche = $serializer->deserialize($recherche_json, Recherche::class, 'json');
Run Code Online (Sandbox Code Playgroud)
和 SerializationPropertyTypeExtractor:
class SerializationPropertyTypeExtractor implements PropertyTypeExtractorInterface {
/**
* {@inheritdoc}
*/
public function getTypes($class, $property, array $context = array())
{
if (!is_a($class, Recherche::class, true)) {
return null;
}
if ('make' !== $property) {
return null;
}
if ('lieu' === $property)
{
return [new Type(Type::BUILTIN_TYPE_OBJECT, true, LieuRecherche::class)];
}
if ('categorie' === $property)
{
return [new Type(Type::BUILTIN_TYPE_OBJECT, true, Categorie::class)];
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
这很好用!
我遇到了类似的问题,并尝试使用自定义 PropertyTypeExtractor 解决该问题。由于我有许多带有嵌套对象的实体,这感觉很麻烦,而且当嵌套对象再次嵌套对象时它也不起作用。
我使用 PhpDocExtractor 和 ReflectionExtractor 找到了一个更好的解决方案,它为您提取属性信息。
$encoder = [new JsonEncoder()];
$extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]);
$normalizer = [new ArrayDenormalizer(), new ObjectNormalizer(null, null, null, $extractor)];
$serializer = new Serializer($normalizer, $encoder);
$result = $serializer->deserialize($data,someEntity::class,'json');
Run Code Online (Sandbox Code Playgroud)
这为我完成了所有工作。我希望这会帮助某人。
参考:我的评论。我知道您正在以经典方式使用序列化器,但我建议您应用推荐的策略模式,这样您就可以完全控制组件并可以轻松扩展。
因此,我们的想法是为规范化和非规范化创建单独的类,如下所示:
<?php
declare(strict_types=1);
namespace App\Denormalizer;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Exception\CircularReferenceException;
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\Exception\LogicException;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
/**
* Class ConfigDenormalizer
* @package App\Denormalizer
*/
class ConfigDenormalizer implements DenormalizerInterface
{
/**
* @param mixed $data
* @param string $class
* @param null $format
* @param array $context
* @return array
*/
public function denormalize($data = [], $class, $format = null, array $context = array())
{
$result = [];
foreach($data as $key => $config) {
$result[ $config['attribute'] ] = $config['valorem'];
}
return $result;
}
/**
* @param mixed $data
* @param string $type
* @param null $format
* @return bool
*/
public function supportsDenormalization($data, $type, $format = null)
{
return $type === self::class;
}
}
Run Code Online (Sandbox Code Playgroud)
<?php
declare(strict_types=1);
namespace App\Normalizer;
use Symfony\Component\Form\Form;
use Symfony\Component\Serializer\Exception\CircularReferenceException;
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\Exception\LogicException;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
/**
* Class WidgetConfigNormalizer
* @package App\Normalizer
*/
class WidgetAttributeNormalizer implements NormalizerInterface
{
/**
* @param object $form
* @param null $format
* @param array $context
* @return array
*/
public function normalize($form, $format = null, array $context = array()): array
{
$result = [];
foreach($form->getData() as $key => $value) {
$result[] = [
'attribute' => (string) $key,
'valorem' => (string) $value,
];
}
return $result;
}
/**
* @param mixed $form
* @param null $format
* @return bool
*/
public function supportsNormalization($form, $format = null)
{
if($form instanceof Form) {
return $form->getName() === 'widgetAttribute';
}
}
}
Run Code Online (Sandbox Code Playgroud)
你会这样称呼它:
//denormalize
$this->denormalizer->denormalize(
json_decode($response->getContent(), true),
ConfigDenormalizer::class
);
//normalize
$form = $this->formFactory->create(myConfigFormType::class);
$form->submit($data);
$this->normalizer->normalize($form);
Run Code Online (Sandbox Code Playgroud)
或者,如果您想使用序列化器(请注意,我们不需要 json_decode):
//deserialize
$array = $this->serializer->deserialize(
$response->getContent(),
ConfigDenormalizer::class,
'json'
);
//serialize
$json = $this->serialize->serialize($form, 'json');
Run Code Online (Sandbox Code Playgroud)
当然,在反规范化器中,您可以将数组转换为普通的旧 php 对象(实体)。或者只是输出一个数组,选择权在你。
这样你所要做的就是将 SerializerInterface 注入到你的控制器中,如下所示:
use Symfony\Component\Serializer\SerializerInterface;
class EmbedController extends Controller
{
/**
* @var SerializerInterface
*/
private $serializer;
public function __construct(SerializerInterface $serializer)
{
$this->serializer = $serializer;
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法也使单元测试变得更加容易,因为一切都是解耦的,因此可以进行模拟。:)
它还值得检查文档: https ://symfony.com/doc/current/components/serializer.html
尤其是顶部的图像,它可以很好地提示您应该如何使用每个类。
希望这可以帮助。
| 归档时间: |
|
| 查看次数: |
8601 次 |
| 最近记录: |