Eloquent将十进制转换为字符串

Sap*_*aik 5 php decimal laravel eloquent

我的模型中有一个十进制字段用于赚钱,我在尝试向此字段添加一些数字时注意到错误的结果.

经过进一步检查,我发现十进制字段被转换为字符串,就像"1245114.00"在修补控制台中一样.

我检查了表格结构,我可以验证该字段确实存在decimal(11,3).

之前问过这个问题,但没有答案.

为什么会这样?

Lui*_*noz 19

您需要在模型中定义哪些字段需要转换为基本属性.

protected $casts = [
    'my_decimal' => 'float',
];
Run Code Online (Sandbox Code Playgroud)

$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

  • 如果这是一个愚蠢的问题,请原谅我。但是,十进制不是比浮点数或双精度数更好的处理货币的方法吗?如果我将小数转换为浮点数并对其进行运算,那会不会违反使用DECIMAL字段存储金额的目的? (3认同)
  • 另一个想法是将它存储为整数,并在需要时转换该值。 (2认同)
  • @commonsense 如果仅使用少量数字,那将是一个好主意。记住 int 通常是一个数字的 32 位表示,因此它可以存储的最大数字是“2,147,483,647”。因此,当以美分存储数百万(例如)时,它会崩溃。 (2认同)
  • @LuisfelipeDejesusMunoz 使用 SQL 的 BIGINT 类型,并且系统总体上正在向 64 位架构发展,我认为溢出不再是一个大问题了。8 字节整数可以表示高达 9 quintillion 的值,因此除非您使用 [2008 年左右的津巴布韦货币](https://medium.com/african-makers/my-brother-went-to-zimbabwe-and-all -he-got-me-was-100-trillion-dollars-1b94cf1916b7) 你不应该用小单位方法溢出。 (2认同)

小智 7

根据Laravel的github仓库上的这个线程:https : //github.com/laravel/framework/issues/11780

这似乎是PDO驱动程序问题。自动将小数转换为字符串。那个线程中的人说这是mysql 5.2驱动程序的问题,有的回滚到5.1。如果您在自己的服务器上,则可以降级。否则,您将不得不将其强制转换为浮动在模型级别。


dRa*_*tol 6

应该是这样,因为 PHP 没有小数类型。如果将小数转换为浮点数,则可能会失去精度。

最好的选择是保持原样,作为字符串。然后用bcmath来操作,它的意思是和字符串一起使用的。


agm*_*984 5

我刚刚花了一些时间分析这个问题,因为我的 Laravel 模型将数据库十进制列显示为字符串。

重要的是,在模型中添加类型转换以浮动确实可以修复它,但如果您像我一样,您会注意到dd(\App\SomeModel::someScope()->get());在模型中添加类型转换后仍然将这些小数列显示为字符串。

当这些值发送到客户端时,它们是整数,因此类型转换确实解决了原始问题,从而允许我的 JavaScript 接收Numbernot String

我只是做出这个答案,这样人们就不会因为专注于dd()输出而浪费时间。我研究了有关 PDO 驱动程序的解决方案,虽然有些可能有优点,但这并不是什么大问题,因为真正的数据库输出被转换为正确的类型。