Here我正在为REST API构建Symfony SDK。大多数数据都是具有嵌套的其他JSON对象的JSON对象。喜欢这里
{
"id": "eng_pl",
"name": "Premier League",
"_links": {
"self": {
"href": "/tournaments/eng_pl"
},
"seasons": {
"href": "/tournaments/eng_pl/seasons/"
}
},
"coverage": {
"id": "eng",
"name": "England",
"_links": {
"self": {
"href": "/territories/eng"
}
}
}
}
反序列化必须生成一个与下面列出的代码生成的对象相等的对象:
$tournament = new Tournament();
$tournament->setId('eng_pl');
$tournament->setName('Premier League');
$coverage = new Territory();
$coverage->setId('eng');
$coverage->setName('England');
$tournament->setCoverage($coverage);
我正在使用我自己的自定义Denormalizers,位于锦标赛对象的denormalizer代码片段下面:
class TournamentDenormalizer implements DenormalizerInterface
{
/**
* @inheritdoc
*/
public function supportsDenormalization($object, $type, $format = null)
{
if ($type != Tournament::class) {
return false;
}
return true;
}
/**
* @inheritdoc
* @return Tournament
*/
public function denormalize($object, $class, $format = null, array $context = array())
{
$tournament = new Tournament();
$tournament->setId($object->id);
$tournament->setName($object->name);
if (isset($object->coverage)) {
/** @var Territory $coverage */
$coverage = ???; //HOWTO how to implement Territory denormalization here???
$tournament->setCoverage(
$coverage
);
}
return $tournament;
}
}
问题是如何在TournamentDenormalizer中访问TerritoryDenormalizer?我看到两个选择:
第一个(我现在正在使用)是将implements DenormalizerAwareInterface
添加到denormalizer类的签名并依赖Symfony\Component\Serializer\Serializer
类:
$serializer = new Symfony\Component\Serializer\Serializer(
[
new TournamentDenormalizer(),
new TerritoryDenormalizer()
], [
new Symfony\Component\Serializer\Encoder\JsonDecode()
]
);
$serializer->deserialize($json, Tournament::class, 'json');
所以在TournamentDeserializer
中,它就像在这里:
if (isset($object->coverage)) {
/** @var Territory $coverage */
$coverage = $this->denormalizer->denormalize(
$object->coverage,
Territory::class,
$format,
$context
);
$tournament->setCoverage(
$coverage
);
}
}
第二种方法 是明确地注入必要的非规范化
$tournamentDenormalizer = new TournamentDenormalizer();
$tournamentDenormalizer->setTerritoryDenormalizer(new TerritoryDenormalizer());
所以在TournamentDeserializer
中,它就像在这里:
if (isset($object->coverage)) {
/** @var Territory $coverage */
$coverage = $this->territoryDenormalizer->denormalize(
$object->coverage,
Territory::class,
$format,
$context
);
$tournament->setCoverage(
$coverage
);
}
}
哪种方法最好?可能有哪些替代方法?
答案 0 :(得分:1)
使用规范化器实现NormalizerAwareInterface
(并最终使用NormalizerAwareTrait
)是可行的方法,此接口已针对此特定用例引入。