我在Eloquent模型中使用了一个小数位字段来表示货币,但是当我尝试将某些数字添加到该字段时,发现结果错误。
进一步检查后,我发现小数位字段被强制转换为字符串,如tinker控制台中的"1245114.00"
。
我检查了表结构,并可以确认该字段确实为decimal(11,3)
。
这个问题曾经在Stack Overflow上被提问过,但没有答案。
为什么会发生这种情况?
我在Eloquent模型中使用了一个小数位字段来表示货币,但是当我尝试将某些数字添加到该字段时,发现结果错误。
进一步检查后,我发现小数位字段被强制转换为字符串,如tinker控制台中的"1245114.00"
。
我检查了表结构,并可以确认该字段确实为decimal(11,3)
。
这个问题曾经在Stack Overflow上被提问过,但没有答案。
为什么会发生这种情况?
您需要在模型中定义哪些字段需要转换为基元属性。
protected $casts = [
'my_decimal' => 'float',
];
在您的模型上,
$casts
属性提供了一种将属性转换为常见数据类型的便捷方法。$casts
属性应该是一个数组,其中键是要转换的属性名称,值是您希望将列转换为的类型。 支持的转换类型包括:integer
、real
、float
、double
、string
、boolean
、object
、array
、collection
、date
、datetime
和timestamp
。
这里有一个非常好的解释:
https://mattstauffer.com/blog/laravel-5.0-eloquent-attribute-casting/
还有文档中的解释:
https://laravel.com/docs/5.5/eloquent-mutators#attribute-casting
2,147,483,647
。因此,当以分为单位存储数百万(例如),程序将会崩溃。 - Luis felipe De jesus Munoz由于PHP没有小数类型,所以这是应该的。如果您将小数转换为浮点数,可能会丢失精度。
最好的选择是将其保留为字符串,然后使用bcmath进行操作,bcmath是用于处理字符串的。
我刚花了一些时间分析这个问题,因为我的 Laravel 模型将数据库十进制列显示为字符串。
重要的是,在模型中添加浮点数类型转换确实可以解决该问题,但如果像我一样,您会注意到在模型添加类型转换后,dd(\ App \ SomeModel :: someScope() - > get())
仍然显示那些十进制列作为字符串。
当这些值被发送到客户端时,它们是整数,因此类型转换确实解决了原始问题,从而使我的 JavaScript 收到 Number
而不是 String
。
我只是提供这个答案,所以一个人不会因为专注于 dd()
输出而浪费时间。我研究了关于 PDO 驱动程序的解决方案,虽然有些也许有价值,但这并不是很重要,因为真正的数据库输出已被转换为正确的类型。
$value = +$model->number_field_decimal
或者
$value = 1*$model->number_field_decimal