我从外部API端点(例如Person API)获得了这样的数组,但是数组键名使用其他语言并且带有下划线-使用我的代码标准是不可接受的。该项目由Symfony 4.x和PHP 7.1运行
[
'first_name_in_other_language' => 'value',
'last_name_in_other_language' => 'value',
...more fields
]
但是我想将其转换为具有有效字段名称的类条目(例如:(Person
不是教义实体-它是存储数据的简单对象)
class Person {private $firstName; private $lastName; ...more fields}
问题:我认为我应该制作某种映射器数组/对象,例如
['first_name_in_other_language' => 'firstName']
但是我找不到与Symfony
相关的这种方法的任何示例
也许是因为这个问题与水化器而不是与序列化器有关?
我从zend hydrator
找到了这段代码there,它似乎支持我需要的功能(new MapNamingStrategy(['published' => 'isPublished'])
):
use Acme\Transaction;
use Zend\Hydrator\NamingStrategy\CompositeNamingStrategy;
use Zend\Hydrator\NamingStrategy\MapNamingStrategy;
use Zend\Hydrator\NamingStrategy\UnderscoreNamingStrategy;
use Zend\Hydrator\ObjectProperty as ObjectPropertyHydrator;
$underscoreNamingStrategy = new UnderscoreNamingStrategy();
$namingStrategy = new CompositeNamingStrategy([
'isPublished' => new MapNamingStrategy(['published' => 'isPublished']),
'publishedOn' => $underscoreNamingStrategy,
'updatedOn' => $underscoreNamingStrategy,
]);
$hydrator = new ObjectPropertyHydrator();
$hydrator->setNamingStrategy($namingStrategy);
$data = $hydrator->extract($transaction);
问题:可以使用Symfony序列化程序或其他Symfony组件对其进行存档吗?
答案 0 :(得分:0)
如果我正确理解了您的问题,则可以为此类添加构造函数,如下所示:
class Person{
private $firstName;
private $lastName;
//other stuff
function __construct($your_api_answer){
$this->firstName = $your_api_answer["first_name_key_of_answer"];
$this->lastName = $your_api_answer["last_name_key_of_answer"];
//initialize other stuff
}
}
$person = new Person($your_api_answer);
答案 1 :(得分:0)
这是一个可行的示例。
<?php
namespace MyCompany\Bundle\SymfonyCustomerBundle\Formatter;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
use Symfony\Component\Serializer\NameConverter\MetadataAwareNameConverter;
use Doctrine\Common\Annotations\AnnotationReader;
use Mycompany\Bundle\SymfonyCustomerBundle\Model\Contact;
class ContactFormatter {
public function __construct()
{
//TODO : Make it as a service injection for all formatter
$classMetadataFactory = new ClassMetaDataFactory(
new AnnotationLoader(new AnnotationReader())
);
$metadataAwareNameConverter = new MetadataAwareNameConverter($classMetadataFactory);
$encoders = [new JsonEncoder()];
$normalizers = [new ObjectNormalizer($classMetadataFactory, $metadataAwareNameConverter)];
$this->serializer = new Serializer($normalizers, $encoders);
}
public function formatToModel(array $rawData): Contact
{
return $this->serializer->denormalize($rawData, Contact::class);
}
public function formatToArray(Contact $contact): array
{
return $this->serializer->normalize($contact);
}
}
以及使用SerializedName批注的模型。
<?php
namespace Mycompany\Bundle\SymfonyCustomerBundle\Model;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Serializer\Annotation\SerializedName;
class Contact
{
/**
* @SerializedName("db_id_contact")
*/
private int $idContact;
/**
* @SerializedName("db_nomContact")
* @Assert\NotBlank
*/
private ?string $lastName = null;
/**
* @SerializedName("db_prenomContact")
* @Assert\NotBlank
*/
private ?string $firstName = null;
public function getIdContact(): int{
return $this->idContact;
}
public function getLastName(): ?string {
return $this->lastName;
}
public function getFirstName(): ?string {
return $this->firstName;
}
public function setIdContact($value){
$this->idContact = $value;
}
public function setLastName(?string $value){
$this->lastName = $value;
}
public function setFirstName(?string $value){
$this->firstName = $value;
}
}