【问题标题】:Doubles losing their decimal places in unit tests双打在单元测试中丢失小数位
【发布时间】:2020-05-16 09:41:38
【问题描述】:

所以我正在将旧的 Laravel 项目从 5.3 升级到 5.4(计划升级到 5.8),但是我的单元测试遇到了问题,其中双打丢失小数位。

这是一个此类测试的示例(是的,我的测试与数据库交互):

$this->user->message_score = 3.42;
$this->user->save();
echo $this->user->fresh()->message_score; // 3

表的迁移:

$table->double('message_score')->nullable();

无论我设置什么数字,小数位都会丢失。 不是向上或向下取整,3.42 变成 3,3.99 也是如此。

Tinker 没有同样的问题。

我认为我遗漏了一些简单的东西。

感谢任何帮助。

编辑

所以我进行了迁移以更新message_score 精度,但我遇到了同样的问题。运行迁移前数据库中显示的长度为(8,2),而我运行的迁移将其推高到(10,8)。迁移如下:

DB::statement('ALTER TABLE `users` MODIFY `message_score` DOUBLE(10,8) NOT NULL DEFAULT 0.0;');

【问题讨论】:

  • 你能不能定期做一些var_dumps 来查看它何时被设置为整数,并分享来自save() 或fresh() 的任何相关代码?
  • 你检查了吗:stackoverflow.com/questions/48516430/… 和 Laravel 文档 laravel.com/docs/5.8/migrations [可用的列类型]
  • @zbee 他们只是标准的 Laravel save() 和 fresh() 方法。话虽如此,使用save() 方法将十进制数与小数位一起保存到数据库中。
  • @Akam 已经看过那个答案并且没有运气,与文档相同。如果您使用->double('message_score') 而不指定精度,它仍然允许小数位,只是没有那么多。

标签: php laravel eloquent phpunit


【解决方案1】:

您应该在迁移中包含精确度:

$table->double('message_score', 8, 2)->nullable();

【讨论】:

  • 澄清一下,需要运行额外的迁移来更新每个具有双精度、浮点数等的表?
  • 在我之前的评论中,我尝试了它,但没有运气。将在问题中添加更多详细信息。
【解决方案2】:

问题与MYSQL连接有关,具体设置PDO::ATTR_EMULATE_PREPARES为true。

PDO::ATTR_EMULATE_PREPARES 允许您在准备好的语句中重用参数,例如,您可以只使用:id 而不是:id1, :id2, :id3。 当它在 PHP >= 7.2 上设置为 true 时,它会导致所有浮点数被强制转换为整数,因此会丢失精度。这是因为 Laravel 不支持这个 PDO 标志。

基本上有两种选择:

将 PDO::ATTR_EMULATE_PREPARES 设置为 false,然后开始唯一命名参数,例如 :id1, :id2, :id3。

或者

将您的浮点数设置为字符串,此时它们将保留小数位,因为 Laravel 将不再将其视为浮点数并将其转换为整数。

如果您想了解更多内容,请查看 GitHub 上的问题:https://github.com/laravel/framework/issues/23850

【讨论】:

    猜你喜欢
    • 2011-08-10
    • 1970-01-01
    • 2016-03-22
    • 2014-03-13
    • 2015-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-26
    相关资源
    最近更新 更多