当小数列映射到类型暗示的浮点属性时,即使未更改,学说也会更新字段

the*_*uts 7 php doctrine doctrine-orm

我有一个用户类,其中包含字段

/**
 * @ORM\Column(type="decimal", precision=12, scale=6)
 */
private float $credit = 0;
Run Code Online (Sandbox Code Playgroud)

或者使用 php8,相同的行为:

private int|float $credit = 0;
Run Code Online (Sandbox Code Playgroud)

如果我加载一个用户,即使没有更改任何内容,在下一次刷新()时,学说也会发送一个查询来更新其信用:

在此输入图像描述

(这是非常危险的,因为信用可能已被另一个脚本同时更改,从而恢复更改。信用不应该直接从应用程序编辑,甚至没有 setCredit() 方法...... )

通过在 preUpdate() 方法中添加一些转储,我发现该值已更改为:

"-10746.000000"(细绳)

到:

-10746.000000(漂浮)

如果我删除私​​有财产上的类型提示,则不会发生这种情况:

private $credit = 0; // Working, credit is not updated to db 
Run Code Online (Sandbox Code Playgroud)

为什么会发生这种情况?我是否做错了什么或者我应该将其报告为错误?

yiv*_*ivi 9

对于字段,Doctrine 将以或 的decimal形式检索数据。此处的文档对此进行了解释。stringnull

由于您将属性定义为 a float,因此您强制 Doctrine 在检索数据时进行一些类型处理,这反过来又导致实体“脏”的混乱:从数据库检索的值不等于存储在财产上,例如'123.12' !== 123.12。

string您应该使用属性的类型decimal。

然后,您可以float在想要执行数学运算时进行转换,或者如果您对精度感兴趣(通常是使用类型时的情况),则可以使用BC Mathdecimal之类的东西。