2016-12-16 82 views
9

Here我正在构建用于REST API的Symfony SDK。大多数数据是嵌套其他JSON对象的JSON对象。喜欢这里Symfony 2使用自定义denormalizers对嵌套对象进行反规范化

{ 
    "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,的解归的代码锦标赛对象片段下方:

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内的TerritoryDe​​normalizer?我看到两个选项:

第一个(我现在用的)被添加到implements DenormalizerAwareInterface类解归签字,并依靠Symfony\Component\Serializer\Serializer类:所以在TournamentDeserializer

$serializer = new Symfony\Component\Serializer\Serializer(
    [ 
     new TournamentDenormalizer(), 
     new TerritoryDenormalizer() 
    ], [ 
     new Symfony\Component\Serializer\Encoder\JsonDecode() 
    ] 
); 
$serializer->deserialize($json, Tournament::class, 'json'); 

它会像这里:

if (isset($object->coverage)) { 
     /** @var Territory $coverage */ 
     $coverage = $this->denormalizer->denormalize(
      $object->coverage, 
      Territory::class, 
      $format, 
      $context 
     ); 
     $tournament->setCoverage(
      $coverage 
     ); 
    } 
} 

第二种方法 是注入必要denormalizers明确

$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 
     ); 
    } 
} 

哪种方法是最好的?还有哪些可行的方法?

回答

1

使您的标准化程序执行NormalizerAwareInterface(并最终使用NormalizerAwareTrait)是要走的路,此接口已引入此特定用例。