【问题标题】:serialize array of objects using Doctrine and JMSSerializer annotations使用 Doctrine 和 JMSSerializer 注释序列化对象数组
【发布时间】:2017-03-15 20:32:56
【问题描述】:

我有模特

    /**
     * @ORM\Table(name="polygon")
     * @ORM\Entity(repositoryClass="MyBundle\Repository\PolygonRepository")
     * @JMS\ExclusionPolicy("none")
     */
    class Polygon {
         /**
          * @var string
          *
          * @ORM\Column(name="polygon", type="json_array")
          * @JMS\Type("array<MyBundle\Model\Point>")
          */
          private $points;

          /***/
    }

在 DB 中,它的存储方式类似于文本 '[{"x":1, "y":1} ...]'

在控制器中我有

/**
 * Matches /polygon exactly
 *
 * @Route("/", name="polygon_list")
 * @Method("GET")
 *
 * @Rest\Get("/")
 *
 */
public function listAction()
{
    return $this->container->get('doctrine.orm.entity_manager')
        ->getRepository('MyBundle:Polygon')
        ->findAll();
}

所以我得到 ReflectionProperty::getValue() 期望参数 1 是对象,给定数组

在 ...vendor/jms/metadata/src/Metadata/PropertyMetadata.php:51

如果只是为了得到结果,可以通过虚拟属性来解决

/**
 * @JMS\Exclude
 */
private $points;

/**
 * @JMS\VirtualProperty
 * @JMS\Type("array<MyBundle\Model\Point>")
 * @JMS\SerializedName("points")
 * @JMS\Groups({"common"})
 *
 * @return array
 */
public function getMyPoints() {
    return [new Point(), new Point()]
}

但是我需要从 POST 以 JSON 形式接收这些点,所以到目前为止我发现的唯一方法是类似于 Doctrine 自定义类型 https://github.com/sonata-project/sonata-doctrine-extensions

唯一不同的是,在 convertToPHPValue 方法中,我添加了额外的类型转换来接收对象而不是 assoc 数组:

// pass my [{"x":1, "y":1} ...]
public function convertToPHPValue($value, AbstractPlatform $platform)
    {
       return array_map(function($a){ return (object)$a;}, json_decode($value));
    }

有没有更干净的解决方案,不添加自定义 Doctrine 序列化?

如果只有这个 ...供应商/jms/metadata/src/Metadata/PropertyMetadata.php:51 有过

return $this->reflection->getValue((object)$obj);

但是

return $this->reflection->getValue($obj); // :(

【问题讨论】:

  • 如果学说字段是 json_array 为什么不尝试将 jmsserializer 转储为字符串?
  • 你可以找到关于它的讨论here

标签: php symfony doctrine-orm fosrestbundle jms-serializer


【解决方案1】:

我的问题完全在于使用@JMS\Type

    class Polygon {
         /**
          * @ORM\Column(name="polygon", type="json_array")
          */
          private $points;

          public function getPoints() { return $this->points;}
          public function setPoints($points) {
               $this->points = $points;
               return $this;
          }
          /***/
    }

工作得很好,感谢@Matteo 指出我让事情复杂化了:)

【讨论】:

  • 这里的反对意见可能是因为您发布了一些虚假文本,然后在宽限期窗口中进行了编辑。投反对票的人可能会注意到并撤回他们的投反对票,但实际上没有明确的退路。我想你能做的就是注意未来不要那样做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-11
  • 1970-01-01
  • 1970-01-01
  • 2019-07-03
  • 1970-01-01
  • 2012-06-22
  • 1970-01-01
相关资源
最近更新 更多