如何在 Symfony 3 中使用回调或任何其他方法规范化给定的 属性?
How to normalize a given property using callback or any other method in Symfony 3?
假设我收到来自 API 电话的以下响应:
[
{
"AgreementNumber": 20266,
"StartDate": "2005-07-01T00:00:00",
"EndDate": "2006-06-30T00:00:00",
"AgreementTypeId": 1,
"CfProgramLevelId": 2,
"TamFlag": 0,
"ParentAgreementNumber": null,
"DistributorId": 16,
"CustomerSiteId": 232,
"RowId": 100,
"Source": "Wonderware",
"ActiveFlg": 1
},
...
]
我正在将该结果映射到 Agreement
实体,如下所示:
$propertyNameConverter = new PropertyNameConverter();
$encoders = [new XmlEncoder(), new JsonEncoder()];
$normalizers = [new ObjectNormalizer(null, $propertyNameConverter), new ArrayDenormalizer(),];
$serializer = new Serializer($normalizers, $encoders);
$entities = $serializer->deserialize($data, "QuoteBundle\Entity\Agreement[]", 'json');
实体是这样的:
class Agreement
{
/**
* @var \DateTime
* @ORM\Column(name="StartDate", type="string", nullable=false)
*/
private $startDate;
/**
* @ORM\OneToOne(targetEntity="QuoteBundle\Entity\AgreementType")
* @ORM\JoinColumn(name="AgreementTypeID", referencedColumnName="AgreementTypeID")
*/
private $agreementType;
/**
* @param \DateTime $startDate
*/
public function setStartDate(\DateTime $startDate)
{
$this->startDate = $startDate;
}
/**
* @param AgreementType $agreementType
*/
public function setAgreementType(AgreementType $agreementType)
{
$this->agreementType = $agreementType;
}
}
每次尝试映射数据时,我都会收到以下错误:
Expected argument of type "DateTime", "string" given
这很好,因为我期待 DateTime
作为 startDate
。这里的解决方案是在将数据映射到实体之前转换|规范化数据。
我已阅读 here 但我无法找到如何将此 "callback" 应用于给定的 属性 因为该示例是一个简单的用例而不是一个复杂的用例。
我试过以下代码:
$dateTimeNormalizer = new GetSetMethodNormalizer();
$dateTimeCallback = function ($dateTime) {
return $dateTime instanceof \DateTime ? $dateTime->format(\DateTime::ATOM) : '';
};
$dateTimeNormalizer->setCallbacks(['startDate' => $dateTimeCallback, 'endDate' => $dateTimeCallback]);
$normalizers = [
new ObjectNormalizer(null, $propertyNameConverter),
new ArrayDenormalizer(),
$dateTimeNormalizer,
];
$serializer = new Serializer($normalizers, $encoders);
但是没有用,因为我仍然遇到与上述相同的错误。我知道有一个 DateTimeNormalizer 但将它作为新条目添加到 $normalizers
数组并不能使其正常工作。结果与上面的意思相同。
我还需要一个回调来将 属性 AgreementTypeId
规范化为 agreementType
因为我很确定它也会失败。 (实际上目前没有被映射,我认为问题是因为名称不匹配)
谁能帮我解决这个问题?
答案是下面几行 - Recursive Denormalization and Type Safety
$encoder = new JsonEncoder();
$normalizer = new ObjectNormalizer(null, null, null, new ReflectionExtractor());
$serializer = new Serializer(array(new DateTimeNormalizer(), $normalizer, new ArrayDenormalizer()), [$encoder]);
$entities = $serializer->deserialize($data, "QuoteBundle\Entity\Agreement[]", 'json');
假设我收到来自 API 电话的以下响应:
[
{
"AgreementNumber": 20266,
"StartDate": "2005-07-01T00:00:00",
"EndDate": "2006-06-30T00:00:00",
"AgreementTypeId": 1,
"CfProgramLevelId": 2,
"TamFlag": 0,
"ParentAgreementNumber": null,
"DistributorId": 16,
"CustomerSiteId": 232,
"RowId": 100,
"Source": "Wonderware",
"ActiveFlg": 1
},
...
]
我正在将该结果映射到 Agreement
实体,如下所示:
$propertyNameConverter = new PropertyNameConverter();
$encoders = [new XmlEncoder(), new JsonEncoder()];
$normalizers = [new ObjectNormalizer(null, $propertyNameConverter), new ArrayDenormalizer(),];
$serializer = new Serializer($normalizers, $encoders);
$entities = $serializer->deserialize($data, "QuoteBundle\Entity\Agreement[]", 'json');
实体是这样的:
class Agreement
{
/**
* @var \DateTime
* @ORM\Column(name="StartDate", type="string", nullable=false)
*/
private $startDate;
/**
* @ORM\OneToOne(targetEntity="QuoteBundle\Entity\AgreementType")
* @ORM\JoinColumn(name="AgreementTypeID", referencedColumnName="AgreementTypeID")
*/
private $agreementType;
/**
* @param \DateTime $startDate
*/
public function setStartDate(\DateTime $startDate)
{
$this->startDate = $startDate;
}
/**
* @param AgreementType $agreementType
*/
public function setAgreementType(AgreementType $agreementType)
{
$this->agreementType = $agreementType;
}
}
每次尝试映射数据时,我都会收到以下错误:
Expected argument of type "DateTime", "string" given
这很好,因为我期待 DateTime
作为 startDate
。这里的解决方案是在将数据映射到实体之前转换|规范化数据。
我已阅读 here 但我无法找到如何将此 "callback" 应用于给定的 属性 因为该示例是一个简单的用例而不是一个复杂的用例。
我试过以下代码:
$dateTimeNormalizer = new GetSetMethodNormalizer();
$dateTimeCallback = function ($dateTime) {
return $dateTime instanceof \DateTime ? $dateTime->format(\DateTime::ATOM) : '';
};
$dateTimeNormalizer->setCallbacks(['startDate' => $dateTimeCallback, 'endDate' => $dateTimeCallback]);
$normalizers = [
new ObjectNormalizer(null, $propertyNameConverter),
new ArrayDenormalizer(),
$dateTimeNormalizer,
];
$serializer = new Serializer($normalizers, $encoders);
但是没有用,因为我仍然遇到与上述相同的错误。我知道有一个 DateTimeNormalizer 但将它作为新条目添加到 $normalizers
数组并不能使其正常工作。结果与上面的意思相同。
我还需要一个回调来将 属性 AgreementTypeId
规范化为 agreementType
因为我很确定它也会失败。 (实际上目前没有被映射,我认为问题是因为名称不匹配)
谁能帮我解决这个问题?
答案是下面几行 - Recursive Denormalization and Type Safety
$encoder = new JsonEncoder();
$normalizer = new ObjectNormalizer(null, null, null, new ReflectionExtractor());
$serializer = new Serializer(array(new DateTimeNormalizer(), $normalizer, new ArrayDenormalizer()), [$encoder]);
$entities = $serializer->deserialize($data, "QuoteBundle\Entity\Agreement[]", 'json');