Десериализация xml в объект в Symfony 4.4.30 с помощью компонента Symfony\Component\Serializer\Serializer
задача: денормализовать xml ответа от https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml в объект с использованием компонента Symfony\Component\Serializer\Serializer
Хочу получить такой объект: `
App\Model\EcbHttpResponse\Envelope Object
(
[subject:protected] =>
[Sender:protected] =>
[Cube:protected] => App\Model\EcbHttpResponse\CubeOuter Object
(
[Cube:protected] => App\Model\EcbHttpResponse\CubeInner Object
(
Array
(
[0] => App\Model\EcbHttpResponse\Cube Object ([currency:protected] => 'USD' ),
[1] => App\Model\EcbHttpResponse\Cube Object ([currency:protected] => 'JPY' ),
)
)
)
)
`
а вместо этого получаю: `
App\Model\EcbHttpResponse\Envelope Object
(
[subject:protected] =>
[Sender:protected] =>
[Cube:protected] => App\Model\EcbHttpResponse\CubeOuter Object
(
[Cube:protected] => App\Model\EcbHttpResponse\CubeInner Object
(
[Cube:protected] => Array
(
[0] => Array
(
[@currency] => USD
[@rate] => 1.1617
[#] =>
)
[1] => Array
(
[@currency] => JPY
[@rate] => 132
[#] =>
)
)
)
)
)
`
код который использую:
<?php
namespace App\Service\CurrencyGet;
use App\Model\Exception\UnexpectedHttpStatusCode;
use App\Service\CurrencyRate\CurrencyRateFactory;
use App\Service\CurrencyRate\CurrencyRateInterface;
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;
abstract class AbstractSource implements CurrencySourceInterface
{
protected ResponseInterface $response;
abstract public function getCurrentRates(): CurrencyRateInterface;
public function __construct(
protected HttpClientInterface $HttpClient,
protected string $url,
)
{
}
/**
* @throws UnexpectedHttpStatusCode|ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|TransportExceptionInterface
*/
protected function getCurrentRateContent(string $type)
{
$this->response = $this->HttpClient->request('GET', $this->url);
$deserializedContent = $this->deserialize($type);
}
/**
* @throws UnexpectedHttpStatusCode|ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|TransportExceptionInterface
*/
private function deserialize (string $type): object|array
{
$normalizers = [
new ArrayDenormalizer(),
new ObjectNormalizer(null, null, null, new ReflectionExtractor())
];
$encoders = [new XmlEncoder()];
$serializer = new Serializer($normalizers, $encoders);
if ($this->response->getStatusCode() !== 200) {
throw new UnexpectedHttpStatusCode($this->response->getStatusCode());
}
//специально кидаю исключение что бы посмотреть объект получившийся
throw new \Exception(print_r($serializer->deserialize($this->response->getContent(), $type, 'xml'),true));
return $serializer->deserialize($this->response->getContent(), $type, 'xml');
}
}
Envelope.php
<?php
namespace App\Model\EcbHttpResponse;
class Envelope
{
protected $subject;
protected $Sender;
protected CubeOuter $Cube;
/**
* @param mixed $subject
*/
public function setSubject($subject): void
{
$this->subject = $subject;
}
/**
* @param mixed $Sender
*/
public function setSender($Sender): void
{
$this->Sender = $Sender;
}
/**
* @param mixed $Cube
*/
public function setCube($Cube): void
{
$this->Cube = $Cube;
}
}
CubeOuter.php
<?php
namespace App\Model\EcbHttpResponse;
class CubeOuter
{
protected CubeInner $Cube;
/**
* @return CubeInner
*/
public function getCube(): CubeInner
{
return $this->Cube;
}
/**
* @param CubeInner $Cube
* @return CubeOuter
*/
public function setCube(CubeInner $Cube): CubeOuter
{
$this->Cube = $Cube;
return $this;
}
}
CubeInner.php
<?php
namespace App\Model\EcbHttpResponse;
class CubeInner
{
/** @var array */
protected array $Cube;
/**
* @return array
*/
public function getCube(): array
{
return $this->Cube;
}
/**
* @param array $Cube
* @return CubeInner
*/
public function setCube(array $Cube): CubeInner
{
$this->Cube = $Cube;
return $this;
}
}
Cube.php
<?php
namespace App\Model\EcbHttpResponse;
class Cube
{
protected string $currency;
protected string $rate;
/**
* @return string
*/
public function getCurrency(): string
{
return $this->currency;
}
/**
* @param string $currency
* @return Cube
*/
public function setCurrency(string $currency): Cube
{
$this->currency = $currency;
return $this;
}
/**
* @return string
*/
public function getRate(): string
{
return $this->rate;
}
/**
* @param string $rate
* @return Cube
*/
public function setRate(string $rate): Cube
{
$this->rate = $rate;
return $this;
}
}