gpt4 book ai didi

symfony - JMSSerializer 按 id 反序列化实体

转载 作者:行者123 更新时间:2023-12-04 14:40:26 25 4
gpt4 key购买 nike

我正在使用 JMSSerializer 反序列化一个 JSON 请求,但我在多对一关系方面遇到了麻烦。我想从给定的 id 反序列化关系实体。例子:

Class Game {


/**
* @var Team
*
* @ORM\ManyToOne(targetEntity="Team")
* @ORM\JoinColumn(name="home_team_id", referencedColumnName="id")
* @JMSSerializer\SerializedName("home")
*/
private $homeTeam;

/**
* @ORM\ManyToOne(targetEntity="Team")
* @ORM\JoinColumn(name="visitor_team_id", referencedColumnName="id")
* @JMSSerializer\SerializedName("visitor")
*/
private $visitorTeam;
}

所以当我得到这个 Json

{"home": "id1", "visitor": "id2"}



获取相关实体。有云吗??我想不通

提前致谢

最佳答案

定制 serializer handler允许这样做。

首先,您需要创建自己的序列化处理程序。像这样的东西:

<?php

namespace AppBundle\Serializer\Handler;

use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bridge\Doctrine\RegistryInterface;
use JMS\Serializer\Context;
use JMS\Serializer\Exception\InvalidArgumentException;
use JMS\Serializer\GenericDeserializationVisitor;
use JMS\Serializer\Handler\SubscribingHandlerInterface;
use JMS\Serializer\VisitorInterface;
use JMS\Serializer\GraphNavigator;

class EntityHandler implements SubscribingHandlerInterface
{
/**
* @var RegistryInterface
*/
protected $registry;

/**
* @return array
*/
public static function getSubscribingMethods()
{
$methods = [];

foreach (['json', 'xml', 'yml'] as $format) {
$methods[] = [
'type' => 'Entity',
'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
'format' => $format,
'method' => 'deserializeEntity',
];

$methods[] = [
'type' => 'Entity',
'format' => $format,
'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
'method' => 'serializeEntity',
];
}

return $methods;
}

/**
* EntityHandler constructor.
* @param RegistryInterface $registry
*/
public function __construct(RegistryInterface $registry)
{
$this->registry = $registry;
}

/**
* @param VisitorInterface $visitor
* @param $entity
* @param array $type
* @param Context $context
* @return mixed
*/
public function serializeEntity(VisitorInterface $visitor, $entity, array $type, Context $context)
{
$entityClass = $this->getEntityClassFromParameters($type['params']);
if (!$entity instanceof $entityClass) {
throw new InvalidArgumentException(
sprintf("Entity class '%s' was expected, but '%s' got", $entityClass, get_class($entity))
);
}

$entityManager = $this->getEntityManager($entityClass);
$primaryKeyValues = $entityManager->getClassMetadata($entityClass)->getIdentifierValues($entity);
if (count($primaryKeyValues) > 1) {
throw new InvalidArgumentException(
sprintf("Composite primary keys does'nt supported now (found in class '%s')", $entityClass)
);
}
if (!count($primaryKeyValues)) {
throw new InvalidArgumentException(
sprintf("No primary keys found for entity '%s')", $entityClass)
);
}

$id = array_shift($primaryKeyValues);
if (is_int($id) || is_string($id)) {
return $visitor->visitString($id, $type, $context);
} else {
throw new InvalidArgumentException(
sprintf(
"Invalid primary key type for entity '%s' (only integer or string are supported",
$entityClass
)
);
}
}

/**
* @param GenericDeserializationVisitor $visitor
* @param string $id
* @param array $type
*/
public function deserializeEntity(GenericDeserializationVisitor $visitor, $id, array $type)
{
if (null === $id) {
return null;
}

if (!(is_array($type) && isset($type['params']) && is_array($type['params']) && isset($type['params']['0']))) {
return null;
}

$entityClass = $type['params'][0]['name'];
$entityManager = $this->getEntityManager($entityClass);

return $entityManager->getRepository($entityClass)->find($id);
}

/**
* @param array $parameters
* @return string
*/
protected function getEntityClassFromParameters(array $parameters)
{
if (!(isset($parameters[0]) && is_array($parameters[0]) && isset($parameters[0]['name']))) {
throw new InvalidArgumentException('Entity class is not defined');
}

if (!class_exists($parameters[0]['name'])) {
throw new InvalidArgumentException(sprintf("Entity class '%s' is not found", $parameters[0]['name']));
}

return $parameters[0]['name'];
}

/**
* @param string $entityClass
* @return EntityManagerInterface
*/
protected function getEntityManager($entityClass)
{
$entityManager = $this->registry->getEntityManagerForClass($entityClass);
if (!$entityManager) {
throw new InvalidArgumentException(
sprintf("Entity class '%s' is not mannaged by Doctrine", $entityClass)
);
}

return $entityManager;
}
}

然后你应该在你的服务配置文件中注册它。如果您使用 yaml,它将是这样的:
custom_serializer_handle:
class: AppBundle\Serializer\Handler\EntityHandler
arguments: ['@doctrine']
tags:
- {name: 'jms_serializer.subscribing_handler'}

在您的实体中,定义 JMSSerializer Type注解
/**
* @var Team
* * @ORM\ManyToOne(targetEntity="Team")
* @ORM\JoinColumn(name="home_team_id", referencedColumnName="id")
* @JMSSerializer\SerializedName("home")
* @JMSSerializer\Type("Entity<AppBundle\Entity\Team>")
* List item
*/
private $homeTeam;

不要忘记清除缓存。
就这样。

关于symfony - JMSSerializer 按 id 反序列化实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42051659/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com