【问题标题】:Symfony serializer returns string instead of floatSymfony 序列化程序返回字符串而不是浮点数
【发布时间】:2019-03-19 15:17:17
【问题描述】:

如何配置 Symfony 序列化器组件以规范化对象(实体)的浮点属性?

详细说明:一个学说实体的taxRate 属性被映射到一个PHP 浮点值。我想用 JSON 表示的控制器做出响应,例如:

{taxRate:0.19}

但我得到的是

{taxRate:"0.19"}

实体的属性和注解的定义是:

class ExampleEntity {
  /**
   * @ORM\Column(type="decimal", precision=3, scale=2, nullable=true)
   * @Groups({"api"})
   */
  protected $taxRate;
}

控制器如下所示:

$serializer = $this->get('serializer');
return new JsonResponse(
  $serializer->normalize(
    $exampleEntity,
    'json',
    [
      'groups' => 'api',
    ]
  )
);

我不喜欢在 JavaScript 端将字符串转换为浮点数的解决方案。我的应用想要断言该属性为 NULL 或 Float 值。

如何做到这一点?

【问题讨论】:

  • 试试type="float"
  • 认真的吗?我试过了,它可以工作。但是 1. 这是在哪里记录的?因为那个注解是针对 Doctrine 的,对吧? 2. 我认为 DECIMAL 使用起来更安全,因为 MySQL FLOAT 类型需要 PHP 语言环境才能使用 '.'作为浮点分隔符,并非总是如此。 3. 谢谢! 4. 有没有办法坚持 DECIMAL 并实现浮点/双精度的转换? (我一直是这么想的)
  • @nifr 你是对的。但感谢 sietse85 的评论,我意识到“错误”的转换发生在序列化之前。我不知道 DECIMAL 被映射/转换为 PHP 字符串。我的错。现在我对这个事实有点不满意:)
  • 好收获。您可以将GetSetMethodNormalizerpublic function getTaxRate(): float { return (float)$this->taxRate; }public function setTaxRate($taxRate) { $this->taxRate = (float)$taxRate; } 一起使用,以防止出现这些转换问题。

标签: php json symfony serialization


【解决方案1】:

对于 decimal 类型的值,从数据库中检索到的值总是转换为 PHP 的字符串类型,如果不存在数据,则为 null。

Doctrine Documentation

如果要使用小数,请更改属性的 getter

public function getTaxRage(): ?float
{
    return is_string($this->taxRate) ? (float) $this->taxRate : $this->taxRate;
}

【讨论】:

    【解决方案2】:

    我对 Symfony 4.4 序列化程序有同样的问题,我不同意你的解决方案。我通过将 type="decimal" 更改为 type="float" 解决了我的问题,因为有些人已经在 cmets 中提出了建议。正确的类型提示是一种很好的做法。既然可以使用浮点数,为什么还要使用字符串?

    浮点型,来自学说文档:

    https://www.doctrine-project.org/projects/doctrine-dbal/en/2.12/reference/types.html#types

    以浮点精度映射和转换数值数据。如果你 只需要对带有分数的数字有一个近似的精度,你 应该考虑使用这种类型。从数据库中检索的值 始终转换为 PHP 的 float/double 类型,如果没有数据,则为 null 现在。

    有关此方法的一些附加信息:

    • 如果您使用服务容器很好地实例化它,Symfony 序列化程序会读取您的 ORM 注释
    • Symfony 序列化程序完全能够将浮点数视为浮点数
    • Doctrine 需要一个浮点精度,PHP 不需要,而且完全没问题。您可以在数据库中插入一个浮点数,Doctrine 会根据需要对其进行四舍五入。

    序列化器的浮点属性示例:

    /**
     * @var float|null
     * @ORM\Column(type="float", precision=6, scale=2, nullable=true)
     */
    protected $ratio;
    
    /**
     * @return float|null
     */
    public function getRatio(): ?float
    {
        return $this->ratio;
    }
    
    /**
     * @param float|null $ratio
     * @return $this
     */
    public function setRatio(?float $ratio): self
    {
        $this->ratio = $ratio;
        return $this;
    }
    

    【讨论】:

      【解决方案3】:

      感谢cmets,我认为问题不是很清楚/可以删除。

      序列化过程很好,是Doctrine的映射我没弄好。

      完全没问题,DECIMAL Doctrine/MySQL 类型映射到 PHP 字符串。 DECIMAL 旨在保证数值的精度。 PHP 的浮点类型不能保证相同的精度。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-02-20
        • 2019-09-09
        • 1970-01-01
        • 2013-12-18
        • 1970-01-01
        • 1970-01-01
        • 2019-07-13
        • 2011-05-13
        相关资源
        最近更新 更多